java实现精确的浮点数运算

java实现精确的浮点数运算

众所周知小数在机器里通常表示为二进制浮点数的形式,而浮点数的精度是有限的:单精度float类型的尾数域(表示数值的部分)是23位,而双精度double类型的尾数域也只有52位(详细参见 浮点数的机器表示
于是,当一个十进制小数不能转换为有限位的二进制数时,这个小数就不能在机器里精确表示
例如0.1在机器里就不能精确表示,其尾数域表现为0011循环:



那么当我们在进行浮点数运算时就可能会遇到一些意想不到的差错(请你试一试下面这段代码的输出是什么):

当我们不需要特别高精度的浮点运算时,可以用printf的%.xf修饰符帮我们保留x位小数,它会帮我们做好四舍五入,这里我们就用%f,默认保留小数点后6位:

还有其他实现四舍五入的方法我们就不讲了,这里来谈谈怎么实现精确的浮点数运算
  Java中要实现精确的浮点数运算常用到Math.BigDecimal类来处理,这里给出几种推荐的给BigDecimal数值初始化的方法:

  • BigDecimal variable = new BigDecimal(string decimal)
    注意这里括号内的参数填入用字符串表示的小数,如:

    BigDecimal varible = new BigDecimal("1.1")
  • BigDecimal variable = BigDecimal.valueOf(double decimal)
    这里可以用BigDecimal提供的静态方法,参数填写正常的浮点数,如:

    BigDecimal varible = BigDecimal.valueOf(1.1)
  • BigDecimal variable = BigDecimal.valueOf(int n,int e)
    这里是用十进制的数值n和阶码e来表示n*10^-e,如

    BigDecimal variable = BigDecimal.valueOf(11,1)

    同样表示1.1

要进行BigDecimal之间的运算就得用BigDecimal提供的静态方法了,如加法add,减法subtract,乘法multiply,除法divide

比如实现我们一开始给出的例子就可以用下面的程序段实现:

可以看到结果为0.9有关java实现精确的浮点数运算的介绍就写到这,想了解更多有关BigDecimal类的信息请访问Java文档-BigDecimal

 

4+
Rhett Peng

软件工程大三在读学生,用个人网站记录学习动态

说点什么

avatar