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

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

我在 comma.The javascript 代码生成的数字与 C# 代码相比少了一个数字后,最后一位数字的精度有问题。

这是简单的 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
}

如何达到相同的精度?

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

实际上returns“0.425451762267059”(本例中没有有效数字+15位小数),而不是后面注释中显示的精度。

所以你会使用:

return num.ToString("G16");

得到“0.4254517622670592”

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

Java脚本 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 第 12.7 节。

有注释

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".

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

这样的东西
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) 检查是否获得了相同的位模式。