2014-11-04 19 views
6

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?

cevap

8

aşağıdaki hata raporu bulduk: O yorumlanır kod vs JITed kodunda biraz farklı sonuçlar dönen bir kayan nokta işlemi bildiriyor ki çok benzer

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

.

Sorun bir hata olarak işaretlenmiş ve giderilmiştir. Bu temelde, gördüğünüz şeyin de bir hata olduğunu ve Oracle'a bildirilmesi gerektiğini iddia ediyorum.

İlgili konular