在JVM上进行浮点运算是否会在所有平台上产生相同的结果?

2021/01/17 11:11 · java ·  · 0评论

我在运行于多台计算机上的应用程序中使用Java,并且所有计算机都需要获得相同的数学运算结果。使用Java的浮点原语是否安全?还是应该只使用定点数学库?

一般而言,不。但是,您可以使用strictfp表达式

在FP-strict表达式中,所有中间值都必须是浮点值集或double值集的元素,这意味着所有FP-strict表达式的结果必须是IEEE 754算术对使用单格式和双格式表示的操作数预测的结果。

在不受FP限制的表达式中,为实现留出了一定的余地,可以使用扩展的指数范围来表示中间结果。粗略地说,最终结果是,在独占使用浮点值集或双精度值集可能导致上溢或下溢的情况下,计算可能会产生“正确答案”。

除了strictfp,还StrictMath要求先验和其他功能的结果是可预测的。

JVM应该一致地实施IEEE规范,并且该规范具有很高的技术性和精确性。在所有平台上,float和double的浮点原语都是相同的。

区别仅在于处理中间结果,并且虚拟机实现可以在评估涉及同一执行框架内的局部表达式的同时使用浮点扩展指数和双扩展指数格式。

因此,如果您有如下代码:

double d1 = 0.342;
double d2 = 1.328479;
double d3 = 4.99384728796;
System.out.println(d1 * d2 / d3);

并且这不是在严格的fp上下文中,可能会在运行时跨不同的JVM产生差异。这是因为在评估表达式d1 * d2 / d3时,在表达式“中间结果” / d3中使用了d1 * d2的中间结果,并且JVM可能使用了float扩展指数和double扩展指数格式存储“中间结果”。

要解决此问题,您可以使用别人在这里回答过的strictfp或StrictMath,或者避免在表达式中使用中间结果。一种方法是将任何中间结果存储在堆中。例如如下:

class MyClass {
    static double d1 = 0.342;
    static double d2 = 1.328479;
    static double d3 = 4.99384728796;
    static double intermediate_result = 0d;
    public static void main(String[] args) {
        intermediate_result = d1 * d2;
        System.out.println(intermediate_result / d3);
    }
}
本文地址:http://java.askforanswer.com/zaijvmshangjinxingfudianyunsuanshifouhuizaisuoyoupingtaishangchanshengxiangtongdejieguo.html
文章标签: ,  
版权声明:本文为原创文章,版权归 admin 所有,欢迎分享本文,转载请保留出处!

文件下载

老薛主机终身7折优惠码boke112

上一篇:
下一篇:

评论已关闭!