20

When running this in a node command-line interface:

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

But in Chrome:

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

Aren't both using the same V8 engine?

Node's result is not even equal to the maximum "integer" value in JavaScript.

Community
  • 1
  • 1
Ludovic C
  • 2,855
  • 20
  • 40
  • Interesting. What does Math.PI/2 by itself result in in both? – p e p Jun 27 '14 at 15:44
  • Same thing! Node : 1.5707963267948966 Chrome : 1.5707963267948966 – Ludovic C Jun 27 '14 at 15:45
  • I'm also able to reproduce this issue and I'm stumped as to why it happens. Great question! – jedmao Jun 27 '14 at 15:48
  • If you take `Math.PI/2` (`1.5707963267948966`) and start plugging it into `Math.tan` with more and more decimal points (starting with `1.57`), the result of `Math.tan(whatever)` becomes `Infinity` at `1.570796326794896` (where the result is `1679930021256638.2`), which is one digit left off – Ian Jun 27 '14 at 15:56

4 Answers4

9

If you look at the v8 implementation of the Math object, you see:

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

Indeed, Math.cos(Math.PI/2) returns an unusual value in Node as well (in fact, the reciprocal of your unusual Math.tan result):

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

So, your question reduces to: Why is Math.cos(Math.PI/2) non-zero in Node <=0.10.24?

This is difficult to answer. The implementation of sine and cosine are supplied by a math-heavy function called TrigonometricInterpolation, which relies on a reverse lookup table of 1800 sample values generated by C++ code, code which is itself generated a Python script when v8 is first installed.

It is also worth noting, however, that the current trig lookup table code very recently replaced an older lookup table, so the current release of Node may not be using the most recent trig lookup table (since new code arrived in v8 on Nov. 22, 2013, but the only pull from v8 into Node prior to the 0.10.24 release in December 2013 was on Nov 11, 2013, eleven days prior to the change). Chrome probably is using up-to-date code, while current stable Node is using different trigonometric code.

apsillers
  • 112,806
  • 17
  • 235
  • 239
5

If you type:

Math.PI/2

Do you get exactly π/2? Nope ;)

Therefore, it can't "accurately" calculate Math.tan(Math.PI/2) as being Infinity because it doesn't have the precision for Math.PI/2.

But in some cases (such as Chrome), the loss of precision is so small that it gets Infinity anyway.

To illustrate this, take a look at this console output:

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

Notice how there are actually two values that result in Infinity? That's the inaccuracy.

Niet the Dark Absol
  • 320,036
  • 81
  • 464
  • 592
4

The thing is that, server has different settings from a browser. Infinity is the variable "Number.POSITIVE_INFINITY" but if you check out another variable, the "Number.MAX_INTEGER" my chrome gives:

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

and 9007199254740991 is smaller than 16331778728383844, so probably chrome decide every number bigger than Number.MAX_INTEGER to be Infinity.

On node js console.log( Number.MAX_INTEGER ) // prints 1.7976931348623157e+308

Chrome and node js has different up and down limits for Numbers.

To sum up, on nodejs Number.MAX_INTEGER is bigger than Math.tan(Math.PI/2) while chrome's Number.MAX_INTEGER is smaller than Math.tan(Math.PI/2) .

So nodejs see a number while chrome see Infinity.

GramThanos
  • 3,572
  • 1
  • 22
  • 34
  • But node's Number.MAX_SAFE_INTEGER returns undefined – Ludovic C Jun 27 '14 at 15:58
  • Thats the point, node has no limit, chrome has a limit, a browser may not do so complex maths. A server may do. Browser execute code that any page gives you. A server execute code that admin want. You can't trust a page but you can trust your admin so u let him do such big and complex maths. – GramThanos Jun 27 '14 at 16:01
  • @Ludo I would think you wouldn't want to limit the size of an integer on a server, whereas on a browser it could open big issues with resource availability. – Dave Briand Jun 27 '14 at 16:01
  • @ThanasisGrammatopoulos my node gives undefined for Number.MAX_INTEGER but 1.7976931348623157e+308 for Number.MAX_VALUE. – Ludovic C Jun 27 '14 at 16:23
  • Probably chrome has 2 variables Number.MAX_SAFE_INTEGER and Number.MAX_INTEGER for some reason of compatibility probably. – GramThanos Jun 27 '14 at 16:27
4

With HEAD version

node -v
v0.11.14-pre

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

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

Ludovic C
  • 2,855
  • 20
  • 40