Math.Tan()近-Pi / 2错在.NET中,对Java中? [英] Math.Tan() near -Pi/2 wrong in .NET, right in Java?

查看:238
本文介绍了Math.Tan()近-Pi / 2错在.NET中,对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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆