2010-05-29 13 views
5

Czy ktokolwiek mógłby mi zadać pytanie, dlaczego wynik tego programu nie jest "inny niż inny"?Liczba zmiennoprzecinkowa w Javie

public static void main(String[] args) 
{ 

float f1=3.2f; 
float f2=6.5f; 

if(f1==3.2) 
System.out.println("same"); 
else 
System.out.println("different"); 

if(f2==6.5) 
System.out.println("same"); 
else 
System.out.println("different"); 
} 

O/P: inny sam

+0

dlaczego to powinno być? –

Odpowiedz

11

6.5 ma skończoną binarną reprezentację: 110,1

Każdy swobodna z co najmniej 4 znaczących bitów może reprezentować to ilość całkowicie.

+110,100000000000000000000 (float)
= 6,5

110,10000000000000000000000000000000000000000000000000 (dwukrotnie)
= 6,5

3,2 z drugiej strony ma nieskończoną binarną reprezentację: 101.0011001100110011 ...

pływaka i dwukrotnie nie ma nieskończonej precyzji, a zatem może tylko przybliżać tę liczbę :(

+101,001100110011001100110 (float)
= 3,2000000476837158203125

101,00110011001100110011001100110011001100110011001101 (dwukrotnie)
= 3,20000000000000017763568394002504646778106689453125

Jak można wyraźnie zobaczyć, liczby te nie są takie same!

+0

+1 do ciebie, ponieważ jest to jedyna odpowiedź, która faktycznie odpowiada na zadane pytanie. Nie wiem, dlaczego PO przyjął inną odpowiedź, która zdecydowanie nie wyjaśnia, dlaczego jedno badanie daje * "to samo" *, a drugie * "inne" *. – NoozNooz42

+2

Dodałbym, że innym powodem jest to, że Java promuje mniej precyzyjne typy do bardziej precyzyjnych typów dla porównania, co umożliwia porównanie 3.2 i 3.2f. Jeśli obcinałby tutaj dłuższy typ, byłyby one takie same, ale na szczęście (podobnie jak C) używa * rozszerzających się prymitywnych konwersji *, aby zrobić to, czego większość ludzi prawdopodobnie oczekiwałby: http://bit.ly/d8Yx3N – tgamblin

+0

@ NoozNooz42: Hej , Mam to również poprawne (: –

3

Ponieważ 3.2f jest wartością float i 3.2 jest wartością double. Liczby zmiennoprzecinkowe są zawsze nieco niedokładne, ponieważ reprezentacja binarna nie może ich dokładnie wprowadzić, więc porównywanie ich pod kątem dokładnej równości jest złym pomysłem. Szczególnie Porównując pływaki z podwójnymi. Wyrażenia takie jak 3.2f == 3.2f są zwykle w porządku, ale nawet te mogą nie działać w niektórych językach, np. jeśli reprezentują liczby w rejestrach dokładniej niż w pamięci.

+0

+1, ponieważ to wyjaśnienie jest znacznie dokładniejsze, niż chciałem napisać. :) – edl

+0

Myślę, że pytanie brzmi, dlaczego jeden z nich powinien być równy. PO spodziewa się, że obie będą nierówne. –

+3

"Liczby zmiennoprzecinkowe są * zawsze * nieznacznie niedokładne" -> źle. float i double mogą reprezentować ułamki z skończonymi reprezentacjami binarnymi, takimi jak 6.5. Zobacz moją odpowiedź dla szczegółów. – fredoverflow

0

"3.2f" jest pływającym typem. "3.2" jest typu podwójnego.

0

Ponadto, myślę, że wszystko z dziesiętną wartością domyślną w podwójnym, więc podczas porównania, musisz dodać "f", jak również if(f2==6.4f).

5

Ponieważ 3.2 nie jest reprezentowany dokładnie jako liczba zmiennoprzecinkowa, a 6.5 to (wskazówka: 6.5 = 13 * 2^(- 1)), a także fakt, że 3.2 jest literałem double, ale 3.2f jest literałem float .

Powiązane problemy