【问题标题】:Are JavaScript numbers deterministic?JavaScript 数字是确定性的吗?
【发布时间】: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 在这里没有精确指定......"。这并不奇怪:对超越函数进行有效且有保证的正确舍入是一个难以解决的问题,而且要求它是不合理的。

标签: javascript ieee-754


【解决方案1】:

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

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

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

【讨论】:

    【解决方案2】:

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

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

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

    (a++) + (++a)
    

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

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

    这里有更长的讨论:

    Javascript evaluation order for operators

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-12-31
      • 2012-05-13
      • 2016-10-20
      • 1970-01-01
      • 1970-01-01
      • 2016-05-12
      • 2021-05-26
      相关资源
      最近更新 更多