他们解释“如何”。我想知道为什么这些语言之间的差异。我期望在相同的输入下得到相似的结果。
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);
}
}
#include "stdio.h"
int main() {
double nine = 9.0;
double pointOhOhOne = 0.001;
double result = nine * pointOhOhOne;
printf("%f", result);
}
#!/usr/bin/env ruby
nine = 9.0
pointOhOhOne = 0.001
result = nine * pointOhOhOne
print result
#!/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之外,每一种语言都只是将float值打印到尽可能多的小数位。
C很容易解释。使用printf(“%f”,result)
,而不指定显式精度值。根据C标准,f
说明符的精度默认为6。因此,精确地打印出小数点后的六位,这就是你看到的。正如@ouah所指出的,将精度设置为18将产生“预期的”输出。这是有损的:超过小数点后第7位的双倍将以相同的方式打印出来,因此不能依赖%f
的输出来精确地重建原始浮动。
这一新特性的目的是减少对浮点数的混淆(尽管这是值得怀疑的),更重要的是提供更易读的、更短的浮点数表示,而不影响往返行为;也就是说,浮点数(repr(x))
总是等于x
,即使repr(x)
由于这种算法而缩短。因此,该算法设法产生一个较短的浮点表示,同时保持“无损”:双赢!
官方的描述是这样说的:
repr(1.1)的新算法更聪明,返回'1.1'。有效地,它搜索所有等价的字符串表示(用相同的基础浮点值存储的字符串),并返回最短的表示。
但如果将浮点数或整数减小或增大一定量,则比较运行得快得多: 更改比较运算符(例如,改用或)不会以任何明显的方式影响时间。 这不仅仅与幅度有关,因为选择较大或较小的值会导致更快的比较,所以我怀疑这是由于位排列的某种不幸方式造成的。
我阅读关于浮点和舍入在浮点算术期间发生的错误。 我读了很多关于IEEE754单精度/双精度格式的文章。我知道有符号位、8(或)11位指数和23(或)52位有效位以及隐式前导位。 我也知道分母不是质因数2的实数不能完全表示,例如二进制中的0.1是0.0001100110011...... 我知道0.1 0.1 0.1不等于0.3,因为舍入误差的累积。 同样,0.5也可以用二进制格式表示,因为它是1/
这样一个看似简单的数字怎么会“太大”而无法在64位内存中表达呢?
问题内容: 我知道浮点数学充其量可能很难看,但我想知道是否有人可以解释以下怪癖。在大多数编程语言中,我测试了0.4到0.2的添加会产生轻微的错误,而0.4 + 0.1 + 0.1会给出非错误。 计算不均的原因是什么,人们可以在相应的编程语言中采取什么措施以获得正确的结果。 在python2 / 3中 在Julia 0.3中也是如此 和Scala: 和Haskell: 但是R v3正确了: 问题答案
我知道浮点数学充其量是很难看的,但我想知道是否有人能解释下面的怪癖。在我测试的大多数编程语言中,将0.4加到0.2会产生轻微的误差,而0.4+0.1+0.1则表示不存在。 这两种计算结果不相等的原因是什么?在各自的编程语言中可以采取什么措施来获得正确的结果。
问题内容: 我在x86 CentOS 6.3(内核v2.6.32)系统上运行。 我将以下功能编译为准字符驱动程序模块,以进行实验,以了解Linux内核如何对浮点运算作出反应。 代码已编译(没想到),因此我插入了模块,并使用来检查日志。日志显示:。 这似乎很奇怪;我以为您不能在Linux内核中执行浮点运算-保存一些异常,例如。模块如何执行浮点运算? 这是因为我在x86处理器上吗? 问题答案: 我以为