Math.sin()Node.js和C#之间的精度不同

时间:2016-10-15 01:47:47

标签: javascript c# node.js math sin

我在逗号后面的最后一位数字的精度有问题。与C#代码相比,javascript代码产生的数字少了一个。

这是简单的Node.js代码

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

这是简单的C#代码

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

如何达到同样的精度?

2 个答案:

答案 0 :(得分:2)

return num.ToString("G15");//0.42545176226705922

实际上返回" 0.425451762267059" (此示例中没有有效数字+ 15位小数),而不是后面注释中显示的精度。

所以你会使用:

return num.ToString("G16");

得到" 0.4254517622670592"

(对于您的示例 - 有效数字始终为0)G16将为16位小数。

答案 1 :(得分:2)

JavaScript Number类型非常复杂。看起来浮点数可能与IEEE 754-2008类似,但某些方面留待实现。见http://www.ecma-international.org/ecma-262/6.0/#sec-number-objects秒12.7。

有一个注释

  

对于某些人来说,toFixed的输出可能比toString更精确   值因为toString只打印足够的有效数字   区分数字与相邻数字值。例如,

     

(1000000000000000128).toString()返回" 1000000000000000100",而   (1000000000000000128).toFixed(0)返回" 1000000000000000128"。

因此,为了获得全数字的准确性,您需要像

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

另外,请注意sin和cos的实现如何在实际算法中允许某些变化的规范。它仅保证在+/- 1 ULP范围内。

使用java打印算法是不同的。即使强制17位数,结果也为0.42545176226705920。

您可以使用Java中的x.toString(2)Double.doubleToLongBits(x)检查是否获得了相同的位模式。