gpt4 book ai didi

java - Math.Tan() near -Pi/2 在 .NET 中错误,在 Java 中正确?

转载 作者:搜寻专家 更新时间:2023-11-01 02:10:11 24 4
gpt4 key购买 nike

我的单元测试在 Math.Tan(-PI/2) 上失败,返回 .NET 中的错误版本。

“预期”值取自 Wolfram 在线(使用 -Pi/2 的拼写常量)。自己看here .

正如在评论中正确观察到的,tan(-pi/2) 的数学结果是无穷大。但是,常量 Math.PI 并不能完美地表示 PI,因此这是一个“接近极限”的输入。

这是代码。

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

我认为这是浮点表示法的问题。

但奇怪的是,Java 中的相同内容确实会返回与 Wolfram 相同的值,直到最后一位数字 - 请参阅 Eclipse 中的评估。 (表达式被裁剪了 - 你必须相信我,它们使用与上面的 MINUS_HALF_PI 相同的常量。)

enter image description here

True
DotNET -1.63317787283838440000E+016
Wolfram -1.63312393531953460000E+016
Java -1.63312393531953700000E+016

如您所见,区别在于:

  • 在 Wolfram 和 .NET 之间:~5.39 * 10^11
  • 在 Wolfram 和 Java 之间:=2.40 * 10^1

那是十个数量级!

那么,您知道为什么 .NET 和 Java 实现如此不同吗?我希望他们都将实际计算推迟到处理器。这个假设对于 x86 来说不切实际吗?

更新

根据要求,我尝试使用 strictfp 在 Java 中运行。没有变化:

enter image description here

最佳答案

整个问题的构建是为了产生一个有倾向性的结果。最接近PI一半的double值为-1.5707963267948966;其他数字被忽略。因此,难怪 C# 和 Java 都检测不到剩余的 14 位数字不是使结果更接近 -PI/2,而是经过精心选择以欺骗 Wolfram Alpha返回一个接近 Java 结果的值。

-1.570796326794896557998981734272 // the number from the question
-1.57079632679489661923132169163975… // the real digits of -PI/2

the end of the double precision

范围内的任何其他数字将四舍五入为相同的 double 数字,包括 the exact double value as used by Java在 Wolfram Alpha 上产生的值与 C# 和 Java 结果都没有任何共同之处。

关于java - Math.Tan() near -Pi/2 在 .NET 中错误,在 Java 中正确?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20287765/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com