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

slf*_*slf 18 floating-point

我读过这些:

他们解释"如何".我想知道为什么这些语言有所不同.考虑到相同的输入,我期待类似的结果.

test.js

#!/usr/bin/env node

var nine = 9.0;
var pointOhOhOne = 0.001;
var result = nine * pointOhOhOne;
console.log(result);
Run Code Online (Sandbox Code Playgroud)

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);
  }

}
Run Code Online (Sandbox Code Playgroud)

test.c的

#include "stdio.h"

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

test.rb

#!/usr/bin/env ruby

nine = 9.0
pointOhOhOne = 0.001
result = nine * pointOhOhOne

print result
Run Code Online (Sandbox Code Playgroud)

test.py

#!/usr/bin/env python

nine = 9.0
pointOhOhOne = 0.001
result = nine * pointOhOhOne

print result
Run Code Online (Sandbox Code Playgroud)

结果:

ruby     0.009000000000000001
python   0.009
node     0.009000000000000001
java     0.009000000000000001
c        0.009000
Run Code Online (Sandbox Code Playgroud)

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

oua*_*uah 17

在我的系统上的C:

printf("%.18f\n", result);

0.009000000000000001
Run Code Online (Sandbox Code Playgroud)

在我的系统上的Python:

print("%.18f" % result)

0.009000000000000001
Run Code Online (Sandbox Code Playgroud)

与其他语言一样,C或Python默认使用其打印功能限制十进制数字的数量.


nne*_*neo 16

@ouah确定语言都表现相同.我的回答旨在解释为什么它们看起来不同.只有两种具有"不同"输出的语言是C和Python.

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

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

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

这个新功能的目的是减少对浮点的混淆(虽然这是有用的),更重要的是提供更人性化的,更短的浮点数表示而不影响往返行为 ; 也就是说,即使由于这种算法而缩短,float(repr(x))也总是等于.因此,算法设法产生更短的浮点表示,同时保持"无损":双赢!xrepr(x)

官方说明说了这么多:

repr(1.1)的新算法更智能并返回'1.1'.实际上,它会搜索所有等效的字符串表示形式(使用相同的基础浮点值存储的字符串表示形式)并返回最短的表示形式.

  • 你写道"除C和Python之外的所有语言都只是将浮点值打印到尽可能多的小数位",但事实并非如此.例如,Java和Javascript打印出需要的小数位数,以区分这个特定的双精度数和两边的数.我不是Ruby的专家,但似乎做了同样的事情.当然,根据凯文在这个问题上的评论,这些语言中的任何一种都可以打印出更多的小数位. (2认同)