Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/356.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 数学,给出奇怪的答案_Java_Precision_Trigonometry - Fatal编程技术网

Java 数学,给出奇怪的答案

Java 数学,给出奇怪的答案,java,precision,trigonometry,Java,Precision,Trigonometry,我有: 我用过: double num1 = sc.nextInt(); 并制作了输出: double sin = Math.sin(Math.toRadians(num1)); 如果我输入num1: 30并且它计算罪恶。它给了我0.4999999999994sin(30°)肯定是0.5,但是没有一本字典包含一个30°的键值0.5,所以计算机需要计算它 公式如上所示 让我们计算sin(30°),30°=π/6,所以f(x)=π/6-π^3/1296-π^5/933120- 在这个过程中,

我有:

我用过:

double num1 = sc.nextInt();
并制作了输出:

double sin  = Math.sin(Math.toRadians(num1));
如果我输入num1:

30并且它计算罪恶。它给了我
0.4999999999994

sin(30°)肯定是0.5,但是没有一本字典包含一个
30°
的键值
0.5
,所以计算机需要计算它

公式如上所示

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


在这个过程中,精度误差可能会导致“不可预测”(实际上是可预测的)问题。

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


这一结果也不会在
双精度中准确表示。由于双精度
的尾数为52位,因此值>=0.25和<0.5的数字可以用关闭2-54的数字表示。用于表示此结果的
double
为0.49999999999444888487687421729788818416595458984375。当使用
System.out.println
打印时,它将在打印一定数量的小数位数后停止,因此它将被截断为0.49999999994,这就是您看到的结果。(显示的位数在[javadoc]中讨论)。

请阅读抱歉,我不认为这是该问题的重复。通常的“浮点数学坏了吗?”解释了为什么像
0.1
这样的数字不能精确表示。但是0.5可以精确表示,所以这个问题的答案一定有所不同。@ajb是的,0.5可以精确表示,但是pi/6不能。所以我们将精确的30转换成不精确的pi/6,然后找到一个不完全为0.5的正弦。我的意见是Java应该提供名为
sindegrees
cosdgrees
tandegrees
的方法来防止这个问题。虽然0.5有一个完美的表示,但肯定没有超越数pi/6弧度,这是sin
的参数。答案与-1 ulp的错误一致(最小精度单位)在53位尾数中,这与浮点计算差不多。我认为这个答案没有抓住要点。
sin
的合同规定结果必须在“correct”的1 ULP范围内但是问题在于sin的参数-,它是π/6不精确的地方。@DavidWallace你是对的,
π/6不精确是这种情况下的实际精度错误。对不起,我以前没有看到。
if(calc.contains("sin")) {
    System.out.println (sin);
}