JavaScript 数字是确定性的吗?

Posted

技术标签:

【中文标题】JavaScript 数字是确定性的吗?【英文标题】:Are JavaScript numbers deterministic? 【发布时间】:2016-06-01 01:14:47 【问题描述】:

javascript 将数字表示为 IEEE 754 双精度数,这是确定性的。更不用说,我看到一些编译器优化可以改变浮点运算的顺序,在不同的运行中带来不确定性。所以,问题是:不使用其他非确定性来源(Math.random 等),Number -> Number JavaScript 函数是否总是会产生与平台和引擎无关的相同结果?

【问题讨论】:

“是的。” JavaScript 被指定为具有数字的 IEEE 754-Double 语义,并且它具有所有数学运算(从语言语义的角度来看)的明确定义的顺序,其中所有中间值必须精确地实现。如果存在不符合 ECMAScript 规范的平台/引擎。 @user2864740:规范大概不要求Math.logMath.sinMath.cos等被正确舍入?任何使用这些的代码都可能无法跨平台给出相同的结果。 @MarkDickinson 您能否详细说明并在答案中说明您的观点? @Viclib:恐怕我对 ECMAScript 的了解不够,无法给出权威的答案。但在该标准的最新版本(第 6 版)中,第 20.2.2 节中有一条注释以“函数 acos、acosh、asin、asinh、atan、atanh、atan2、cbrt、cos、cosh、 exp、expm1、hypot、log、log1p、log2、log10、pow、random、sin、sinh、sqrt、tan 和 tanh 在这里没有精确指定......"。这并不奇怪:对超越函数进行有效且有保证的正确舍入是一个难以解决的问题,而且要求它是不合理的。 【参考方案1】:

一些编译器优化可以改变浮点运算的顺序,在不同的运行中带来不确定性

ECMAScript 规范没有讨论这种优化。然而,一般而言,预计(就像某些TypedArray 算法明确指出的那样)“优化不得在算法的指定行为中引入任何可观察到的变化。”并且运算符的评估顺序相当在 ECMAScript 中严格指定。

因此,除非执行此类操作的实现证明是错误的(并且还需要确定其标准合规性),否则我们可以假设答案是

【讨论】:

【参考方案2】:

猜测您指的是特定于语言的非确定性,而不是任何特定于 IEEE-754 的东西。

许多其他语言,例如C 具有undefinedimplementation-specific 行为,这允许编译器为该处理器发出非常紧凑的代码,但代价是很多陷阱。

例如,在C 语言中,这个表达式:

(a++) + (++a)

可以以两种不同的顺序进行评估,您可以获得两个有效的答案。

但是,EcmaScript 3(和 5)指定了表达式的操作顺序,因此任何 JavaScript 平台都应该以完全相同的方式执行操作。

这里有更长的讨论:

Javascript evaluation order for operators

【讨论】:

以上是关于JavaScript 数字是确定性的吗?的主要内容,如果未能解决你的问题,请参考以下文章

1,4,2 是由 Java 中的原始类型表示的吗? [关闭]

IEEE 754-2008 是确定性的吗?

所有的javascript回调都是异步的吗?如果不是,我怎么知道哪些是?

firefox下载excel表格时候下载下来的excel名称是乱码,有知道如何转码的吗? 最好有具体的实现代码

函数声明是非静态的吗?

在javascript中,空字符串总是作为布尔值是假的吗?