Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/359.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java IEEE 64位754双精度,要避免的值_Java_Performance_Floating Point_Double - Fatal编程技术网

Java IEEE 64位754双精度,要避免的值

Java IEEE 64位754双精度,要避免的值,java,performance,floating-point,double,Java,Performance,Floating Point,Double,我遇到的情况是,绩效非常重要。我的算法的核心是一种方法,它使用两个double原语进行一些基本计算。此方法在每次运行算法时被调用超过1000万次 代码看起来像这样 public int compare(double xA, double xB, double yA, double yB); double x = xA * xB; double y = yA * yB; double diff = x - y; return (diff < 0.0 ?

我遇到的情况是,绩效非常重要。我的算法的核心是一种方法,它使用两个
double
原语进行一些基本计算。此方法在每次运行算法时被调用超过1000万次

代码看起来像这样

public int compare(double xA, double xB, double yA, double yB);

    double x = xA * xB;
    double y = yA * yB;

    double diff = x - y;

    return (diff < 0.0 ? -1 : (diff > 0.0 ? 1 : 0));

}
public int compare(双xA、双xB、双yA、双yB);
双x=xA*xB;
双y=yA*yB;
双差=x-y;
收益率(差值<0.0-1:(差值>0.0-1:0));
}
参数
xA
yA
从集合中获取其值。这个集合可以在代码中进行调整。根据我在集合中输入的值,我看到了巨大(大约两倍)的性能差异。如果集合中包含
0.1
0.3
,则性能会受到很大影响。将该设置保持为
0.5的倍数可获得最佳性能

编译器是否将
x*0.5
优化为
x>>1
等?或者这是因为不能用二进制定义
0.1

我想更好地理解这种情况,这样我可以优化它。我想这可能是一个相当困难的问题,除非有人确切地知道javac和jvm(在我们的例子中是hotspot)是如何处理双重乘法的。

只有几个想法:

  • 如果值是0.5的倍数,则中的有效位将很少,因此乘法所需的圈数较少似乎是可行的。实际上,乘法的有效位似乎不是一个问题,因为现代处理器对于double只需要两个周期(如中所述)

    例如,我认为0.5、1、2、4等的尾数都是零(第一个“1”是隐式的)。对于.75、1.5、3等,在m.s.b.中为“1”,其后为全零。而0.1将使用所有的有效位精度来表示,即使这样也会有一个小的误差

  • 关于返回的结果:是否存在任何问题?。我的意思是,也许这也会这样:

    return Math.signum(x-y);
    
  • 如果不重要的话,你可以考虑使用单次(浮标)。(不过,如果这意味着你要从双人来回转换,那么这可能不值得)


是的,signum将起作用,但这意味着返回时将强制转换为int,因此我避免了它。您确定性能差异直接存在于此例程中,而不是更改xA和yA导致返回不同结果的后果吗,因此,更改此例程返回后执行的内容?您可以通过删除该行并将返回替换为
return xy来消除减法?1 : 0;
。如果可用的调整延伸到xA和yA的值p和q可以被p/q和1替换的点,则可以消除乘法,留下
double x=xA*xB;双y=yB(取决于通常的浮点舍入问题)。感谢您及时拒绝,非常感谢。没问题。我已将系统移到整数。整个过程是一个比较图中路径成本的启发式方法,最初的想法是将0.0作为“无距离”,1.0作为“无限距离”,但由于需要缓存子路径长度,我们不得不转向更简单的加法启发式方法。因此,不再需要浮点值。然而,这个问题仍然存在。