2012-10-22 20 views
5

Powiel możliwe:
Retain precision with Doubles in java
Moving decimal places over in a doubleJava: Obliczenia zwracające błędną odpowiedź?

Na przykład coś tak proste, jak to:

public class WrongAnswer { 
    public static void main(String[] args) { 
    System.out.println(100*1.1); 
    } 
} 

drukuje 110.00000000000001 zamiast 110. Korzystanie inne numery zamiast 100 * 1.1 daje również dużo cyfr z losową cyfrą na koniec, który nie jest właściwy ..

Jakieś pomysły?

+5

Witamy w cudownym świecie liczb zmiennoprzecinkowych, gdzie wszystko jest przybliżone, a miejsca dziesiętne nie mają znaczenia. –

+0

Duplikat http://stackoverflow.com/search?q=java+double+precision –

Odpowiedz

3

W 100*1.11.1 nie jest wykwalifikowany i tak domyślnie jest double podczas 100 jest domyślnie int.
Wynik mnożenia jest także double ze względu na upcast z 100 i dlatego otrzymujesz ten wynik.

+0

Obsada "int" działa tutaj, ale tylko przez przypadek. W innych kontekstach możesz otrzymać o jeden mniej niż się spodziewasz. –

+0

@TedHopp: Tak, zgadzam się. – Cratylus

+0

100,0d * 1.1d daje ten sam wynik (110.00000000000001) – chrome

4

Większość obliczeń zmiennoprzecinkowych obejmuje błędy zaokrąglania. W twoim przypadku występują dwa błędy zaokrąglania: konwersja (dziesiętnie) 1.1 do zmiennoprzecinkowego (nie ma dokładnej reprezentacji dla 1.1 w IEEE 754 zmiennoprzecinkowy - czyli tego, co używa Java), a następnie pomnożenie przez 100. Zobacz doskonały artykuł What Every Computer Scientist Should Know About Floating-Point Arithmetic dla więcej informacji.

0

Jako odpowiedź, staje się podwójna stąd format. Aby wydrukować wartości closest int/long, lepiej użyć Math.round() funkcję:

System.out.println(Math.round(100*1.1)); 

Staje się to ważne, gdy mnożą się z bardziej precyzyjnych liczb np

System.out.println(Math.round(100*1.199)); //--> prints 112 
    System.out.println((int)(100*1.199)); //--> prints 111 
+2

@Negatywny użytkownik : Proszę zostawić komentarz, aby zrozumieć problem. –