浮点数 – 为什么浮点运算在某些语言中显示不同?

我已经读过这些:

> Why Are Floating Point Numbers Inaccurate?
> http://floating-point-gui.de/

他们解释“怎么样”。我想知道为什么这些语言有所不同。我预期类似的结果给出相同的输入。

test.js

#!/usr/bin/env node

var nine = 9.0;
var pointOhOhOne = 0.001;
var result = nine * pointOhOhOne;
console.log(result);

test.java

public class test {

  public static void main(String[] argv) {
    double nine = 9.0d;
    double pointOhOhOne = 0.001d;
    double result = nine * pointOhOhOne;
    System.out.println(result);
  }

}

test.c的

#include "stdio.h"

int main() {
  double nine = 9.0;
  double pointOhOhOne = 0.001;
  double result = nine * pointOhOhOne;
  printf("%f", result);
}

test.rb

#!/usr/bin/env ruby

nine = 9.0
pointOhOhOne = 0.001
result = nine * pointOhOhOne

print result

test.py

#!/usr/bin/env python

nine = 9.0
pointOhOhOne = 0.001
result = nine * pointOhOhOne

print result

结果:

ruby     0.009000000000000001
python   0.009
node     0.009000000000000001
java     0.009000000000000001
c        0.009000

要点:https://gist.github.com/reklis/6694ad5fb01991a79a1a

最佳答案
@ouah确定这些语言的行为都相同。我的回答旨在解释为什么它们不同。只有两种具有“不同”输出的语言是C和Python。

很明显,除了C和Python之外的每种语言都是将浮点值打印到尽可能多的小数位。

C很容易解释。您使用printf(“%f”,result),而不指定显式精度值。根据C标准,f说明符的精度默认为6.因此,正好打印出六个小数位,这是您看到的。如@ouah所说,将精度设置为18将产生“预期”输出。这是有损的:在小数点后第七位不同的两倍将被打印出来,所以%f的输出不能依赖于精确重构原始浮点数。

Python有点棘手。基于David Gay的工作,Python 3.1引入了一种新的浮点repr算法。与该功能相对应的Python问题在这里:http://bugs.python.org/issue1580.此功能也被反映到Python 2.7。

这个新功能的意图在于减少浮点数上的混淆(尽管这是有用的),更重要的是提供更多的人机可读的较短的浮点数表示,而不影响往返行为;即,float(repr(x))总是等于x,即使repr(x)由于该算法而被缩短。因此,该算法可以产生较短的浮点数表示,同时保持“无损”:双赢!

官方说明很多:

The new algorithm for repr(1.1) is smarter and returns ‘1.1’. Effectively, it searches all equivalent string representations (ones that get stored with the same underlying float value) and returns the shortest representation.

转载注明原文:浮点数 – 为什么浮点运算在某些语言中显示不同? - 代码日志