我在逗号后面的最后一位数字的精度有问题。与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
}
如何达到同样的精度?
答案 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)
检查是否获得了相同的位模式。