我读过这些:
他们解释“如何”。我想知道为什么这些语言有所不同。考虑到相同的输入,我期待类似的结果。
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
答案 0 :(得分:17)
在我系统的C中:
printf("%.18f\n", result);
0.009000000000000001
在我的系统上使用Python:
print("%.18f" % result)
0.009000000000000001
C或Python与其他语言一样,默认情况下使用其打印功能限制小数位数。
答案 1 :(得分:15)
@ouah确定语言的行为都相同。我的回答旨在解释为什么它们看起来不同。只有两种语言有"不同"输出是C和Python。
显然,除了C和Python之外的每种语言都只是将浮点值打印到尽可能多的小数位。
C很容易解释。您使用printf("%f", result)
,而不指定显式精度值。根据C标准,f
说明符的精度默认为6.因此,打印出正好六位小数,这就是您所看到的。正如@ouah所说,将精度设置为18将产生"预期"输出。这是有损的:超过小数点后7位的双打将以相同的方式打印出来,因此%f
的输出不能依赖于精确重建原始浮点数。
Python有点棘手。 Python 3.1基于David Gay的工作引入了一种新的浮点repr
算法。与此功能对应的Python问题在于:http://bugs.python.org/issue1580。此功能也被反向移植到Python 2.7。
这个新功能的目的是减少对浮点的混淆(虽然这有点可疑),更重要的是提供更人性化的,更短的浮点数表示而不影响往返行为;也就是说,float(repr(x))
总是等于x
,即使由于此算法缩短了repr(x)
。因此,算法设法产生更短的浮点表示,同时保持"无损":双赢!
官方说明说了这么多:
repr(1.1)的新算法更智能,并返回' 1.1'。实际上,它会搜索所有等效的字符串表示形式(使用相同的基础浮点值存储的字符串表示形式)并返回最短的表示形式。