繁体   English   中英

Java和C#中的数学“pow”返回略有不同的结果?

[英]Math “pow” in Java and C# return slightly different results?

我正在将程序从C#移植到java。 我遇到了一个事实

Java的

Math.pow(0.392156862745098,1./3.) = 0.7319587495200227

C#

Math.Pow( 0.392156862745098, 1.0 / 3.0) =0.73195874952002271

最后一位数字导致进一步计算的充分差异。 有没有办法模仿c#的战队?

感谢名单

只是为了确认Chris Shain写的是什么,我得到了相同的二进制值:

// Java
public class Test
{
    public static void main(String[] args)
    {
        double input = 0.392156862745098;
        double pow = Math.pow(input, 1.0/3.0);            
        System.out.println(Double.doubleToLongBits(pow));
    }
}

// C#
using System;

public class Test
{
    static void Main()
    {
        double input = 0.392156862745098;
        double pow = Math.Pow(input, 1.0/3.0);            
        Console.WriteLine(BitConverter.DoubleToInt64Bits(pow));
    }
}

两者的输出:4604768117848454313

换句话说,double值是完全相同的位模式,您看到的任何差异(假设您得到相同的结果)都是由于格式而不是值的差异。 顺便说一下,那双的确切值是

0.73195874952002271118800535987247712910175323486328125

现在值得注意的是,在浮点运算中会出现明显奇怪的事情,特别是当优化在某些情况下允许80位算术而在其他情况下不允许等等时。

正如Henk所说,如果最后一两位的差异导致您出现问题,那么您的设计就会被打破。

如果您的计算对这种差异敏感,那么您将需要其他措施(重新设计)。

最后一位数字导致进一步计算的充分差异

这是不可能的,因为它们是相同的数字 double精度不足以区分0.73195874952002270.73195874952002271 ; 他们都被表示为

0.73195874952002271118800535987247712910175323486328125.

不同之处在于舍入:Java使用16位有效数字而C#使用17位。但这只是一个显示问题。

Java和C#都从Math.Pow返回一个IEEE浮点数(特别是一个double)。 您看到的差异几乎肯定是由于您将数字显示为十进制时的格式。 底层(二进制)值可能是相同的,您的数学问题在其他地方。

浮点运算本质上是不精确的。 您声称C#答案“更好”,但它们都不是那么准确。 例如,Wolfram Alpha(确实更准确)给出了以下值:

http://www.wolframalpha.com/input/?i=Pow%280.392156862745098%2C+1.0+%2F+3.0%29

如果一个单位在第17位的差异导致后来的计算出错,那么我认为你的数学存在问题,而不是Java的pow实现。 您需要考虑如何重新构建计算,以便它们不依赖于这些微小的差异。

无论语言如何,17位数的精度是任何 IEEE浮点数都能做到的最佳值:

http://en.wikipedia.org/wiki/Double-precision_floating-point_format

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM