为什么node不将Math.tan(Math.PI/2)评估为Infinity但Chrome V8会这样做?

Lud*_*c C 19 javascript math v8 infinity node.js

在节点命令行界面中运行时:

> Math.tan(Math.PI/2)
16331778728383844 
Run Code Online (Sandbox Code Playgroud)

但在Chrome中:

> Math.tan(Math.PI/2)
Infinity
Run Code Online (Sandbox Code Playgroud)

是不是都使用相同的V8引擎?

节点的结果甚至不等于JavaScript中最大"整数"值.

aps*_*ers 8

如果你看一下对象v8实现Math,你会看到:

function MathTan(x) {
  return MathSin(x) / MathCos(x);
}
Run Code Online (Sandbox Code Playgroud)

实际上,Math.cos(Math.PI/2)在Node中返回一个不寻常的值(事实上,你不寻常的Math.tan结果的倒数):

> Math.cos(Math.PI/2)
6.123031769111886e-17  // in Chrome, this is 0
Run Code Online (Sandbox Code Playgroud)

所以,你的问题简化为:为什么Math.cos(Math.PI/2)Node <= 0.10.24中的非零?

这很难回答.正弦和余弦的实现由一个称为数学的函数提供,该函数TrigonometricInterpolation依赖于由C++代码生成的1800个样本值的反向查找表,这些代码本身在首次安装v8时生成Python脚本.

然而,值得注意的是,当前的trig查找表代码最近替换了较旧的查找表,因此当前版本的Node可能没有使用最新的trig查找表(因为新代码于11月22日到达v8) ,2013年,但在2013年12月0.10.24发布之前从V8进入节点的唯一一次是2013年11月11日,即变更前11天.Chrome可能正在使用最新代码,而当前稳定的Node正在使用不同的三角代码.


Nie*_*sol 5

如果您键入:

Math.PI/2
Run Code Online (Sandbox Code Playgroud)

你能准确地得到 π/2 吗?不 ;)

因此,它不能“准确地”计算Math.tan(Math.PI/2)为 is,Infinity因为它没有Math.PI/2.

但在某些情况下(例如 Chrome),精度损失很小,Infinity无论如何都会损失。

为了说明这一点,请看一下这个控制台输出:

Math.PI/2  
> 1.5707963267948966  

Math.tan(1.5707963267948964)  
> 5039790063769915  

Math.tan(1.5707963267948965)  
> Infinity  

Math.tan(1.5707963267948966)  
> Infinity  

Math.tan(1.5707963267948967)  
> -5039790063769915
Run Code Online (Sandbox Code Playgroud)

请注意实际上有两个值导致Infinity? 这就是不准确之处。