Java 1.8.0_20'ye yükselttikten sonra, test sistemimiz hata bildirdi, ancak kod değiştirilmedi. Ben, aynı giriş parametreleriyle çağrılan Math.pow()
'un, yeniden adlandırılan çağrılar üzerine farklı sonuçlar vereceğini öğrendim. Java 1.8.0_11'de beklendiği gibi davranır ve her zaman aynı değeri döndürür, ancak Java 1.8.0_20 ve üstü ile bazen biraz farklı değerler döndürür.Math.pow, tekrarlanan çağrılarda farklı sonuçlar verir
Bu, Math.pow yields different result depending on java version sorusuna benzer, ancak pow() sonuçlarının bir VM içinde farklı olması nedeniyle farklıdır. Java 1.8.0_20 altında çalışacak ve hotspot -Xint
ile arasında açık olup olmadığını daha yüksek
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);
}
}
Testi Java 1.8.0_11 altında başarısız veya vermediğinde
aşağıdaki JUint testi başarısız olur. Pow() 'nin katı matematik versiyonu tutarlı sonuçlar verir. Hotspot JIT'in, belirli giriş değerleri için farklı sonuçlar veren, pow() 'in farklı uygulamasına geçen bazı optimizasyonlar yapmaktan şüpheleniyorum. Bir matematiksel fonksiyon deterministik olmalı ve tutarlı ve tekrarlanabilir sonuçlar vermelidir.
Bu bir hata mı yoksa özellik mi?