PrOgrAMmer PrOgrAMmer - 1 month ago 6
Node.js Question

Math.sin() Different Precision between Node.js and C#

I have a problem in precision in the last digit after the comma.The javascript code generates one less Digit in compare with the C# code.

Here is the simple Node.js code

var seed = 45;
var x = Math.sin(seed) * 0.5;
console.log(x);//0.4254517622670592


Here is the simple C# code

public String pseudorandom()
{
int seed = 45;
double num = Math.Sin(seed) * (0.5);
return num.ToString("G15");//0.42545176226705922
}


How to achieve the same precision?

Answer

The JavaScript Number type is quite complex. It looks like floating point number will probably be like IEEE 754-2008 but some aspects are left to the implementation. See http://www.ecma-international.org/ecma-262/6.0/#sec-number-objects sec 12.7.

There is a note

The output of toFixed may be more precise than toString for some values because toString only prints enough significant digits to distinguish the number from adjacent number values. For example,

(1000000000000000128).toString() returns "1000000000000000100", while (1000000000000000128).toFixed(0) returns "1000000000000000128".

Hence to get full digit accuracy you need something like

seed = 45;
x = Math.sin(seed) * 0.5;
x.toFixed(17);
// on my platform its "0.42545176226705922"

Also, note the specification for how the implementation of sin and cos allow for some variety in the actual algorithm. It's only guaranteed to within +/- 1 ULP.

Using java the printing algorithm is different. Even forcing 17 digits gives the result as 0.42545176226705920.

You can check you are getting the same bit patterns using x.toString(2) and Double.doubleToLongBits(x) in Java.