Javascript中浮点数的精度可以成为非确定性的来源吗?

时间:2012-04-26 13:45:43

标签: javascript math non-deterministic

相同的数学运算可以在不同的架构或浏览器中返回不同的结果吗?

4 个答案:

答案 0 :(得分:12)

其他答案不正确。根据{{​​3}}(第15.8.2节)

  

注意函数的行为acos,asin,atan,atan2,cos,exp,   除了以外,没有精确指定log,pow,sin,sqrt和tan   要求表示某些参数值的特定结果   边界的利益案件。

     

...

     

虽然算法的选择是   留给实现,建议(但没有指定   该标准)实现使用近似算法   对于fdlibm中包含的IEEE 754算法,可自由分发   Sun Microsystems的数学库


但是,即使指定了 的实现,所有浮点运算的确切结果依然依赖于浏览器/体系结构。 包括乘法和除法等简单操作!!

原因是IEEE-754允许系统在ECMAScript 5.1 specs进行64位浮点计算,导致与使用与结果相同精度的系统产生不同的舍入结果。这正是higher-precision than the result的原因,这就是为什么在C(和javascript)中我们有时会有x86 (Intel) architecture does,即使在同一台机器上也是如此!

这是一个cos(x) != cos(y) even though x == y,因为这意味着,如果无法禁用更高精度的计算(就像C#的情况那样),那些游戏几乎根本不能使用浮点计算。然而,这通常不是Javascript游戏的问题,因为它们通常是客户端 - 服务器。

答案 1 :(得分:3)

如果我们假设每个浏览器供应商都遵循 IEEE 标准+ ECMA规范,并且在实施时没有人为错误,那么就没有任何区别。

答案 2 :(得分:1)

虽然ECMAScript语言规范5.1版规定数字是对应于IEEE 754浮点数的原始值,这意味着计算应该一致:

http://www.ecma-international.org/publications/files/ecma-st/ECMA-262.pdf

  

4.3.19数值

     

原始值对应于双精度64位二进制格式IEEE 754值

     

请注意       Number值是Number类型的成员,是数字的直接表示。

正如BlueRaja指出的那样,第15.8.2节中有一点需要注意:

  

函数acos,asin,atan,atan2,cos,exp,log的行为,   这里没有精确指定pow,sin,sqrt和tan ......

意思是,至少在某些情况下,对数字的操作的结果是依赖于实现的,因此可能不一致。

答案 3 :(得分:0)

我的两分钱 - @goldilocks笔记和其他人暗示你不应该在浮点数上使用==或!=。那么“确定性”是什么意思?在不同的机器上行为总是一样的吗?显然,这取决于你所说的“同样的行为”。

嗯,在“相同”的一个愚蠢的文字级别,当然不是,物理位将在例如32位与64位机器。所以解释就出来了。

好的,在两台不同的机器上运行相同输出的程序也一样吗?一般语言中没有,因为C程序可以使用未定义的内存执行某些操作,例如从未初始化的位读取。

好的,任何有效的程序也会在不同的机器上执行相同的操作吗?好吧,我会说在浮点数上使用==和!=的程序与读取未初始化内存的程序一样无效。我个人不知道Javascript标准是否会破坏==和!= on浮动的行为,以至于它定义得很好,如果不是kooky,那么如果这是你的确切问题,你将不得不看到其他的答案。你能编写一个与标准相关的未定义输出的javascript代码吗?永远不要阅读标准(其他答案有点覆盖),但是对于我的兴趣,这是没有意义的,因为产生你所谓的不确定行为的程序开始时是无效的。