我对Java是否使用IEEE 754标准来实现其浮点运算感兴趣。 Here我在文档中看到了这种情况:



据我了解,IEEE 754的积极方面是提高浮点运算的精度,因此,如果我在Java中使用doublefloat,计算的精度是否会与BigDecimal中的相同?如果不是,那么在 Math 类中使用IEEE 754标准有什么意义呢?

最佳答案



IEEE-754为多种浮点类型定义了标准。多年以来,它们都是二进制浮点数。这就是Java的floatdouble的含义:float是32位IEEE-754二进制浮点值(标准称为 binary32 )。 double是64位的(标准称为 binary64 )。这些二进制浮点数对于计算机而言非常有效,但是由于它们以二进制形式工作,而我们以十进制形式工作,因此存在一些期望值不匹配的情况。例如,0.1不能精确地存储在double中,并且会出现诸如0.1 + 0.2之类的奇怪现象,结果变成0.30000000000000004。有关详细信息,请参见Is floating point math broken?。例如,它们不是财务计算的好选择。
BigDecimal是一个Java类,它以任意精度实现十进制小数。它比使用double慢得多,但是结果符合我们的十进制想法(例如0.1 + 0.2将是0.3)。

IEEE-754的2008版增加了重要的新格式,尤其是 decimal32 decimal64 decimal128 。这些是十进制浮点数,因此它们的工作方式与我们相同。 0.1可以准确地存储在decimal64中。 0.1 + 0.20.3中的decimal64。但是,据我所知,它们与您的问题并没有真正的关系。

由于BigDecimal在一定程度上早于IEEE-754 2008,因此它定义了自己的语义。



JDK9在Math中添加了执行IEEE-754 2008规范定义的操作的新操作(例如 fma ,它执行fused multiply-add),因此为了清楚起见,它引用IEEE-754 2008规范定义了这些操作。

更多阅读:

  • IEEE-754 on Wikipedia
  • BigDecimal JavaDoc
  • 09-25 22:23