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.log
、Math.sin
、Math.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
具有undefined
或implementation-specific
行为,这允许编译器为该处理器发出非常紧凑的代码,但代价是很多陷阱。
例如,在C
语言中,这个表达式:
(a++) + (++a)
可以以两种不同的顺序进行评估,您可以获得两个有效的答案。
但是,EcmaScript 3(和 5)指定了表达式的操作顺序,因此任何 JavaScript 平台都应该以完全相同的方式执行操作。
这里有更长的讨论:
Javascript evaluation order for operators
【讨论】:
以上是关于JavaScript 数字是确定性的吗?的主要内容,如果未能解决你的问题,请参考以下文章
1,4,2 是由 Java 中的原始类型表示的吗? [关闭]
所有的javascript回调都是异步的吗?如果不是,我怎么知道哪些是?