2016-12-22 13 views
22

Właśnie natknąłem się na definicję NaN w Double.class. Mówi:Dlaczego istnieje "d" w definicji Double.NaN = 0.0d/0.0?

/** 
    * A constant holding a Not-a-Number (NaN) value of type 
    * {@code double}. It is equivalent to the value returned by 
    * {@code Double.longBitsToDouble(0x7ff8000000000000L)}. 
    */ 
    public static final double NaN = 0.0d/0.0; 

Wiem, że zgodnie ze specyfikacją Java literały te reprezentują ten sam numer: 0.0, 0.0d i 0.0D.

również do innych stałych, one nie używać „d” przyrostek:

public static final double POSITIVE_INFINITY = 1.0/0.0; 
public static final double NEGATIVE_INFINITY = -1.0/0.0; 

Dlaczego trzeba pisać przyrostek D do pierwszej części 0.0 w definicji NaN?

Czy to było celowo, czy przypadkowo?

+6

Istnieje możliwość, że jest to po prostu programowanie defensywne na części implementatora. Sądząc po TODO i/lub skomentowanym kodzie, JDK nie jest dokładnie złotym standardem programowania. –

+10

Jest również całkowicie możliwe, że jest to tylko historyczny artefakt (kto wie, może w Dębowym '0.0' był literał float zamiast). –

+10

@MarkRotteveel prawidłowa, zgodnie z [ta wersja specyfikacji językowej Oak] (http://www.eecs.harvard.edu/~waldo/oakSpec.pdf): "2.0f lub 2.0F lub 2.0 float". –

Odpowiedz

25

Według Oak language spec, format pływających literałów punktowych były:

  • 2.0d lub 2.0D podwójne
  • 2.0f lub 2.0F lub 2,0 pływak

ale zmieniło się to do znanego sposobu Java przez Java version 1.0

A zmiennoprzecinkowych 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.

Zmiana mogła być wykonana tak, aby była zgodna z C-like languages, gdzie brak sufiksu oznacza podwójne.

Tak więc d wydaje się być historycznym reliktem; chociaż w połączonej wersji specyfikacji Oak (która jest "wstępna"), istnieje uwaga dotycząca tego, że NaN nie jest jeszcze zaimplementowany. Być może został on zaimplementowany w nieco późniejszej wersji i pozostał taki sam na zawsze.

(Rekwizyty do Mark Rotteveel, aby dowiedzieć się o specyfikację języka dębowego).

+7

Przypomnij mi, że następnym razem będę musiał użyć Google'a;) –

6

Nie ma różnicy między 0.0 i 0.0d, ponieważ Java domyślnie podwaja liczbę reprezentującą liczby zmiennoprzecinkowe.

Mimo, że kod jest bardziej czytelny jak w wielu językach, float jest domyślnym, jak to było w Oakewoluowały późniejszy Java tak wygląda historycznej kwestii.

--Link znaleziona przez Andy'ego Turnera.

8

Zgodnie ze specyfikacją języka 0.0 jest taka sama jak 0.0d

JLS Section 3.10.2 opisuje to w następujący sposób:

Ruchomy punkt dosłowny jest typu float, jeśli jest sufiksem z literą ASCII F lub f; w przeciwnym razie jego typ jest podwójne i może być ewentualnie sufiksem z literą ASCII D lub D

Jednym ze sposobów dokonywania numer dosłownego zmiennoprzecinkowych, jest za pomocą „” w liczbie.

Przyczyna, dla której twórcy używają przyrostka d, nie jest znana. Ale często ma to na celu zwiększenie przejrzystości lub zmniejszenie nakładu pracy wymaganego od czytelnika przy zrozumieniu tego kodu. Zasady mogą być znane niektórym, ale nie wszystkim. Wartości domyślne mogą być inne w innych językach. Dlatego w wielu przypadkach lepiej jest napisać bardziej szczegółową wersję.

Innym przykładem jest nawiasy:

double a = b + c * d; 

vs

double a = b + (c * d); 

Wolę jedną z nawiasami, ponieważ jest łatwiejszy do czytania (nawet jeśli wszyscy programiści wiedzą, że są równe).