gpt4 book ai didi

java - Math.pow 在重复调用时产生不同的结果

转载 作者:塔克拉玛干 更新时间:2023-11-03 05:01:45 27 4
gpt4 key购买 nike

升级到Java 1.8.0_20后我们的测试系统报错,但是代码没有改。我发现,使用完全相同的输入参数调用的 Math.pow() 在重复调用时会产生不同的结果。在 Java 1.8.0_11 中,它的行为符合预期并始终返回相同的值,但在 Java 1.8.0_20 及更高版本中,它有时会返回略有不同的值。

这类似于问题 Math.pow yields different result depending on java version ,但有所不同,因为 pow() 的结果在一个 VM 中不同。

以下 JUint 测试在 Java 1.8.0_20 及更高版本下运行时失败

import static org.junit.Assert.assertEquals;

import java.util.function.BiFunction;

import org.junit.BeforeClass;
import org.junit.Test;

public class PowerTest {

private static final int N = 1000000;
private static final double base = 5350.456329377186;
private static final double exp = 2.0;

private static double eval(final BiFunction<Double, Double, Double> f) {
return f.apply(base, exp);
}

private void loop(final BiFunction<Double, Double, Double> f) {
final double x = eval(f);
for (int i = 0; i < N; i++) {
final double p = eval(f);
assertEquals("i=" + i, x, p, 0);
}
}

@BeforeClass
public static void info() {
System.out.println("Java " + System.getProperty("java.version"));
}

@Test
public void mathPow() {
loop(Math::pow);
}

@Test
public void strictMathPow() {
loop(StrictMath::pow);
}
}

测试不会在 Java 1.8.0_11 下失败,或者如果使用 -Xint 关闭热点。 pow() 的严格数学版本产生一致的结果。我怀疑热点 JIT 会做一些优化,切换到 pow() 的不同实现,这会为某些输入值产生不同的结果。数学函数应该是确定性的,并且应该产生一致且可重现的结果。

这是错误还是功能?

最佳答案

我发现了以下错误报告:

JDK-7021568 : Double.parseDouble() returns architecture dependent results

它非常相似,因为它报告浮点运算在 JIT 代码和解释代码中返回的结果略有不同。

该问题已标记为错误并已修复。在此基础上,我认为您所看到的也是一个错误,应该报告给 Oracle。

关于java - Math.pow 在重复调用时产生不同的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26746623/

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