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

Joã*_*imo 13 javascript math non-deterministic

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

Blu*_*eft 13

其他答案不正确.根据ECMAScript 5.1规范(第15.8.2节)

注:该功能ACOS的行为,ASIN,ATAN,ATAN2,COS,EXP,日志,战俘,罪恶,开方,棕褐色不正是这里只是其中要求对代表的利益边界情况某些参数值的具体结果.

...

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


然而,即使实现指定的确切结果所有浮点运算将仍然依赖于浏览器/架构. 这包括简单的操作,如乘法和除法!!

原因是IEEE-754允许系统以高于结果的精度进行64位浮点计算,导致与使用与结果相同精度的系统产生不同的舍入结果.这正是x86(英特尔)架构所做的,这就是为什么在C(和javascript)中我们有时cos(x) != cos(y)甚至x == y可以拥有,即使在同一台机器上!

对于联网的点对点游戏来说是一个大问题,因为这意味着,如果无法禁用更高精度的计算(如C#的情况),那些游戏几乎不能使用浮点计算一点都不 但是,这通常不是Javascript游戏的问题,因为它们通常是客户端 - 服务器.

  • @João:是的,但这与你的问题正交.由于浮点不准确,每个人都知道我们可能有`tan(1)!= sin(1)/ cos(1)`.问题不在于它们是否相等,而是在某些`x`中,`tan(x)`在所有浏览器/机器中总是完全相同.答案仍然是NO,但与浮点不准确无关 - 这是因为`tan(x)`没有在javascript中精确定义,并且因为IEEE-754允许进行扩展精度计算.如果这两件事情不真实,答案是肯定的,它总是一样的. (2认同)

del*_*ver 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 的行为...

这意味着,至少在某些情况下,数字运算的结果取决于实现,因此可能不一致。