Math.sin给出了奇怪的答案

时间:2016-11-24 01:52:22

标签: java precision sin

我有:

double num1 = sc.nextInt();

我用过:

double sin  = Math.sin(Math.toRadians(num1));

并输出:

if(calc.contains("sin")) {
    System.out.println (sin);
}

如果我输入了num1:

30并计算罪。它给了我0.49999999999999994

2 个答案:

答案 0 :(得分:2)

π/ 6无法在计算机中准确表示(也无法在纸上准确表示)。这将导致结果有点偏离。使用Unix高精度计算器“bc”(注意:我不知道它对于正弦和余弦有多精确),我发现程序中的实际值将是π/ 6 +ε,其中ε是关于5.3604 x 10 -17 。使用sin的公式( x + y ),预期结果应为sinπ/6cosε+sin∈cosπ/ 6。 cosε约为1 - 10 -33 ,因此这种差异不足以影响结果。然而,sinεcosπ/ 6约为4.64×10 -17 。所以实际结果应该是0.4999999999999999535774978而不是0.5。

此结果也不会在double中完全表示。因为double具有52位的尾数,其值为&gt; = 0.25且<1的数字。 0.5可以用偏离2 -54 的数字表示。用于表示此结果的double将为0.499999999999999944488848768742172978818416595458984375。当使用System.out.println打印时,它将在打印一定数量的小数位后停止,因此会被截断为0.49999999999999994,这是您看到的结果。 (显示的位数在[http://docs.oracle.com/javase/8/docs/api/java/lang/Double.html#toString-double-](this javadoc中讨论。)

答案 1 :(得分:0)

sin(30°)肯定是0.5,但是没有包含值为30°的{​​{1}}键的字典,因此计算机需要计算它。

enter image description here

上面显示了公式。

让我们计算sin(30°),30°=π/ 6,所以f(x)=π/ 6 - π^ 3/1296 - π^ 5/933120 - ....

然后在此过程中,准确性错误可能导致“不可预测的”(实际上可预测的)问题。