Math.Tan()近-Pi / 2错在.NET中,对Java中? [英] Math.Tan() near -Pi/2 wrong in .NET, right in Java?
问题描述
我有一个 Math.Tan(-PI / 2)
返回错误版本的.NET。
I have an unit test failing on a Math.Tan(-PI/2)
returning the wrong version in .NET.
在'预期'值是从钨在线(使用拼写出常数-Pi / 2)。 查看一下这里。
The 'expected' value is taken from Wolfram online (using the spelled-out constant for -Pi/2). See for yourselves here.
由于正确的评论指出,棕褐色的数学结果(-pi / 2)是无穷大。然而,恒 Math.PI
不完全重新present PI,所以这是一个接近极限的输入。
As correctly observed in the comments, the mathematical result of tan(-pi/2) is infinity. However, the constant Math.PI
does not perfectly represent PI, so this is a 'near the limit' input.
这里的code。
double MINUS_HALF_PI = -1.570796326794896557998981734272d;
Console.WriteLine(MINUS_HALF_PI == -Math.PI/2); //just checking...
double tan = Math.Tan(MINUS_HALF_PI);
Console.WriteLine("DotNET {0:E20}", tan);
double expected = -1.633123935319534506380133589474e16;
Console.WriteLine("Wolfram {0:E20}", expected);
double off = Math.Abs(tan-expected);
Console.WriteLine(" {0:E20}", off);
这是什么会打印:
True
DotNET -1.63317787283838440000E+016
Wolfram -1.63312393531953460000E+016
5.39375188498000000000E+011
我还以为它是浮点再presentation的问题。
I thought it's an issue of floating-point representation.
奇怪的是,虽然,在同样的事情的的Java 的不会返回相同的值钨,下降到最后一位 - 看到它在Eclipse中进行评估。 (这位前pressions被裁剪 - 你一定要相信我,他们使用相同的常数 MINUS_HALF_PI
以上)
Strangely though, the same thing in Java DOES return the same value as Wolfram, down to the last digit - see it evaluated in Eclipse. (The expressions are cropped - you'll have to believe me they use the same constant as MINUS_HALF_PI
above.)
True
DotNET -1.63317787283838440000E+016
Wolfram -1.63312393531953460000E+016
Java -1.63312393531953700000E+016
正如你所看到的,所不同的是:
As you can see, the difference is:
-
钨和.NET之间
- :
〜5.39 * 10 ^ 11
钨和Java之间的 - :
= 2.40 * 10 ^ 1
- between Wolfram and .NET:
~5.39 * 10^11
- between Wolfram and Java:
=2.40 * 10^1
这是 10个数量级!
因此,任何想法,为什么.NET和Java实现相差这么多?我希望他们两个只是推迟实际运算的处理器。这是不切实际的假设为86?
So, any ideas why the .NET and Java implementations differ so much? I would expect them both to just defer the actual computing to the processor. Is this assumption unrealistic for x86?
根据要求,我试图在Java中运行具有 strictfp
。无变化:
As requested, I tried running in Java with strictfp
. No change:
推荐答案
整个问题是构建创建一个倾向性的结果。该双
值最接近一半PI是 -1.5707963267948966
;其他数字将被忽略。因此,这也难怪,无论是C#还是Java检测,其余的14多个数字是的没有的转动结果接近 -PI / 2
,但仔细选择诱骗Wolfram Alpha的返回值接近到Java的结果。
The entire question is constructed to create a tendentious result. The double
value closest to half PI is -1.5707963267948966
; the other digits are just ignored. So it’s no wonder that neither C# nor Java detect that the remaining 14 more digits are not turning the result closer to -PI/2
, but carefully chosen to trick Wolfram Alpha to return a value close to the result of Java.
-1.570796326794896557998981734272 // the number from the question
-1.57079632679489661923132169163975… // the real digits of -PI/2
↑
the end of the double precision
在范围内的任何其他数字,将得到变成一样的双
数字包括的使用的Java 收益率对Wolfram Alpha的有什么共同点两者都不是,在C#还是Java结果的值精确的双重价值。
Any other number within the range that would get rounded to the same double
number including the exact double value as used by Java yields to a value on Wolfram Alpha having nothing in common with neither, the C# nor Java result.
这篇关于Math.Tan()近-Pi / 2错在.NET中,对Java中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!