2012-12-31 16 views
30

Dlaczego trzeba podać przyrostek f w postaci literowej?Java: Dlaczego musisz określać literę "f" w literałach typu float?

+3

Ponieważ w przeciwnym razie nie będzie to _float_ literał. – SLaks

+1

Mimo że jest to C, może ci się spodobać ten quiz o stałych subtelnościach zmiennoprzecinkowych. Wierzę, że każde z pięciu pytań działałoby dokładnie tak samo w Javie. http://blog.frama-c.com/index.php?post/2011/11/08/Floating-point-quiz –

+0

możliwy duplikat [dlaczego f jest umieszczany po wartościach zmiennoprzecinkowych?] (http: // stackoverflow. com/questions/9748160/why-f-is-place-after-float-value) –

Odpowiedz

39

Ponieważ w przeciwnym razie domyślnie jest to double, który jest częściej używanym typem zmiennoprzecinkowym niż float.

Z Java Language Specification, section 3.10.2:

Ruchomy punkt dosłowny jest typu float, jeśli jest sufiksem z literą ASCII F lub F; w przeciwnym razie jego typ jest podwójny i opcjonalnie może zostać dodany z literą D lub d ASCII (§ 4.2.3).

(Osobiście wolałbym nie było domyślne, aby było jasne, we wszystkich przypadkach, ale to inna sprawa).

+1

Ale dlaczego mamy opóźnienie typu, jeśli domyślnie jest to inny typ? Rozumiem, że double to tylko 64-bitowy float, ale czy jest jakiś głębszy sens robienia tego? – stackoverflow

+1

@stackoverflow: Co masz na myśli? Typ * literału * jest nieco niezależny od typu używanej zmiennej. Na przykład możesz użyć literału "float" i przypisać go do zmiennej "double". W większości przypadków typ wyrażenia jest niezależny od kontekstu, w którym jest używany. (Istnieją sytuacje, w których typy są generowane, ale jest to szczególny przypadek.) –

+1

@stackoverflow Java obsługuje [zwężenie konwersji] (http://docs.oracle.com/javase/specs/jls/se7/html/jls- 5.html # jls-5.2) podczas przypisywania literałów do prymitywów. Dlatego możesz mieć 'float f = 1.0;' nawet jeśli '1.0' jest podwójne.Sądzę, że jest to obsługiwane, ponieważ jest jednoznaczne - w przeciwieństwie do używania literału z wywołaniem metody, na przykład. – McDowell

28

Ponieważ unsuffixed literały zmiennoprzecinkowe są dwuosobowe, a zaokrąglenie oznacza, że ​​nawet małe literały mogą przyjmować różne wartości po zaokrągleniu w celu unoszenia się i podwójnego. Można to zaobserwować na następującym przykładzie:

float f = (float) 0.67; 
if(f == 0.67) 
    System.out.print("yes"); 
else 
    System.out.print("no"); 

Wyjście będzie no, ponieważ 0,67 ma inną wartość, gdy zaokrąglona unosić niż dzieje się to przy zaokrągleniu dwukrotnie. Z drugiej strony:

float f = (float) 0.67; 
if(f == 0.67f) 
    System.out.print("yes"); 
else 
    System.out.print("no"); 

& hellip; wyjścia yes.

EDIT
drugim przykładzie

if(0.67 == 0.67f) 
    System.out.print("Equal"); 
else 
    System.out.print("Not Equal"); 
4

są dwa pływające typów punktów, które mogą być przedstawione jak np 100.0. Tylko jeden może być domyślny. Ze względu na swoją ograniczoną precyzję, pływak jest wyjątkowo wyspecjalizowanym typem. Normalny przypadek jest podwójny, więc jest to odpowiednie ustawienie domyślne.

Na nowoczesnych procesorach, float i double mają podobną wydajność obliczeniową. Jedynym przypadkiem użycia float są duże tablice w krytycznych sytuacjach, które wymagają ograniczonej precyzji. Użycie opcji float podwaja liczbę wartości zmiennoprzecinkowych, które pasują do jednej linii pamięci podręcznej. Nawet wtedy ustalenie, czy dane zmiennoprzecinkowe daje wystarczającą dokładność dla danego obliczenia, rzadko jest banalne.

+0

Dziękuję za odpowiedź – stackoverflow

Powiązane problemy