Ste*_*nko 9 c# java math floating-accuracy
我正在将程序从C#移植到java.我遇到了一个事实
Java的
Math.pow(0.392156862745098,1./3.) = 0.7319587495200227
Run Code Online (Sandbox Code Playgroud)
C#
Math.Pow( 0.392156862745098, 1.0 / 3.0) =0.73195874952002271
Run Code Online (Sandbox Code Playgroud)
最后一位数字导致进一步计算的充分差异.有没有办法模仿c#的战队?
感谢名单
Jon*_*eet 35
只是为了确认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));
}
}
Run Code Online (Sandbox Code Playgroud)
两者的输出:4604768117848454313
换句话说,double值是完全相同的位模式,您看到的任何差异(假设您得到相同的结果)都是由于格式而不是值的差异.顺便说一下,那双的确切值是
0.73195874952002271118800535987247712910175323486328125
Run Code Online (Sandbox Code Playgroud)
现在值得注意的是,在浮点运算中会出现明显奇怪的事情,特别是当优化在某些情况下允许80位算术而在其他情况下不允许等等时.
正如Henk所说,如果最后一两位的差异导致您出现问题,那么您的设计就会被打破.
Hen*_*man 18
如果您的计算对这种差异敏感,那么您将需要其他措施(重新设计).
dan*_*n04 13
最后一位数字导致进一步计算的充分差异
这是不可能的,因为它们是相同的数字.A double
没有足够的精度来区分0.7319587495200227
和0.73195874952002271
; 他们都被表示为
0.73195874952002271118800535987247712910175323486328125.
Run Code Online (Sandbox Code Playgroud)
不同之处在于舍入:Java使用16位有效数字而C#使用17位.但这只是一个显示问题.
Java和C#都从Math.Pow返回一个IEEE浮点数(特别是一个double).您看到的差异几乎肯定是由于您将数字显示为十进制时的格式.底层(二进制)值可能是相同的,您的数学问题在其他地方.