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

时间:2014-06-27 15:41:40

标签: javascript node.js math v8 infinity

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

> Math.tan(Math.PI/2)
16331778728383844 

但是在Chrome中:

> Math.tan(Math.PI/2)
Infinity

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

节点的结果甚至不等于maximum "integer" value in JavaScript

4 个答案:

答案 0 :(得分:8)

如果查看v8 implementation of the Math object,您会看到:

function MathTan(x) {
  return MathSin(x) / MathCos(x);
}

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

> Math.cos(Math.PI/2)
6.123031769111886e-17  // in Chrome, this is 0

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

这很难回答。正弦和余弦的实现由称为TrigonometricInterpolation的重数学函数提供,该函数依赖于由C ++代码生成的1800个样本值的反向查找表,代码本身生成a Python script when v8 is first installed

然而,值得注意的是,当前的trig查找表代码very recently replaced an older lookup table,因此当前版本的Node可能没有使用最新的trig查找表(因为新代码于11月到达v8)。 2013年12月22日,但2013年12月0.10.24发布之前的the only pull from v8 into Node是2013年11月11日,即更改前的11天。 Chrome可能使用的是最新代码,而当前稳定的Node使用的是不同的三角代码。

答案 1 :(得分:4)

问题是,服务器具有与浏览器不同的设置。 无穷大是变量" Number.POSITIVE_INFINITY"但如果你检查另一个变量," Number.MAX_INTEGER"我的chrome给出了:

console.log( Number.MAX_INTEGER ) // prints 9007199254740991

和9007199254740991小于16331778728383844,因此chrome可能会将大于Number.MAX_INTEGER的每个数字都确定为无穷大。

在节点js上 console.log(Number.MAX_INTEGER)//打印1.7976931348623157e + 308

Chrome和节点js对Numbers有不同的上下限制。

总而言之, nodejs Number.MAX_INTEGER 大于 Math.tan(Math.PI/2) chrome Number.MAX_INTEGER 小于 Math.tan(Math.PI/2)

所以 nodejs看到一个数字,而 chrome看到Infinity

答案 2 :(得分:4)

如果输入:

Math.PI/2

你得到π/ 2吗?没有;)

因此,它无法“准确地”将Math.tan(Math.PI/2)计算为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

注意实际上有两个值导致Infinity?那是不准确的。

答案 3 :(得分:4)

使用HEAD版本

node -v
v0.11.14-pre

node
> Math.tan(Math.PI/2)
Infinity

https://github.com/joyent/node/issues/7852