2009-09-18 12 views

Odpowiedz

22

Po wypróbowaniu prostego programu (przy użyciu 0 i 100, aby pokazać różnicę między "specjalnymi" stałymi i ogólnymi) kompilator Sun Java 6 wypisze ten sam kod bajtowy dla 1 i 2 (przypadki 3 i 4 są identyczne z 2 w przypadku kompilatora).

Tak na przykład:

double x = 100; 
double y = 100.0; 

kompiluje do:

0: ldc2_w #2; //double 100.0d 
3: dstore_1 
4: ldc2_w #2; //double 100.0d 
7: dstore_3 

Jednak nie widzę nic w Java Language Specification gwarantującą tej kompilacji poszerzenie stałych wyrażeń. Nie ma czasu kompilacji zwężenie w przypadkach takich jak:

byte b = 100; 

określonej w section 5.2, ale to nie całkiem to samo.

Może ktoś z oczu ostrzejsze niż ja mogę znaleźć gwarancji gdzieś tam ...

+0

Czy możesz zasugerować dobry zasób, w którym można przeczytać o ldc2_w i innych instrukcjach? –

+2

Specyfikacja JVM: http://java.sun.com/docs/books/jvms/ –

2

Ostatnie 3 powinny być identyczne. Literał po prawej stronie jest już podwójny. "D" lub "D" jest niejawne, gdy masz literał dziesiętny.

Pierwsza jest nieco inna, ponieważ 0 jest literałem, który zostanie rozszerzony do podwójnego. Nie wiem, czy to w tym przypadku powoduje inny kod bajtowy; wynik powinien i tak być identyczny.

+0

Dziękuję za odpowiedź, wiem, że wyniki są identyczne, chcę poznać różnice pod maską. –

+0

Dla "0.0", "0.0d" i "0.0D" nie ma naprawdę żadnych różnic pod maską. Są to trzy sposoby na napisanie podwójnego dosłowności, wszystkie są dokładnie równoważne. – Jesper

-2

dla Javy Nie wiem dokładnie, w C może to być naprawdę niebezpieczne, jeśli nie podasz tego D na końcu, ponieważ nie zmieni on górnych bajtów, co może mieć wpływ na to, że w Twojej zmiennej liczba kłamstw, której faktycznie nie zrobiłeś wtrącić!

W Javie miałem naprawdę duży problem z instancją BigDecimal - nowy BigDecimal (0) i nowy bigDecimal (0L) to NIE to samo, możesz poczuć to, jeśli zmigrujesz swój kod z Java 1.4 do Java 1.5. Nie wiem, dlaczego byli zaniedbani, może musieli to zrobić w ten sposób.

+1

Twoja odpowiedź nie odpowiada na pytanie. To, co dzieje się w języku C, nie ma znaczenia i nie ma wpływu na BigDecimals. –

13

Dla pierwszego z nich:

double dummy = 0; 

liczbą całkowitą dosłowne 0 przekształca się dwukrotnie z rozszerzającym się prymitywnym konwersji , patrz 5.1.2 Widening Primitive Conversion w specyfikacji języka Java. Zauważ, że robi to w całości kompilator, nie ma żadnego wpływu na wygenerowany kod bajtowy.

Dla innych te:

double dummy = 0.0; 
double dummy = 0.0d; 
double dummy = 0.0D; 

Te trzy są dokładnie takie same - 0.0, 0.0d i 0.0D są tylko trzy różne sposoby pisanie double dosłowne. Zobacz 3.10.2 Floating-Point Literals w JLS.