2011-07-20 8 views

Odpowiedz

13

Długa x tworzysz nie jest wartością oczekiwano. Jest w zakresie całkowitym. Aby utworzyć tęskni, przeznaczenie:

final long x = 24L*60L*60L*1000L*1000L; 
final long y = 24L*60L*60L*1000L; 
System.out.println(x/y); 

x ty komputerowej, w zakresie liczb całkowitych, był 500654080. To podzielone przez y (= 86400000), daje w wyniku 5.794607407407407.... Java obcina część dziesiętną, która powoduje 5.

Dodając L po numerze dosłowne, poinformować kompilator skompilować go jako long zamiast int. Wartość oczekiwana dla x to 86400000000. Ale został skompilowany jako int.

Możemy odtworzyć niewłaściwą wartość dla x (500654080) przez odcięcie go do int:

// First correct 
long x = 24L*60L*60L*1000L*1000L; 
/* x = `86400000000`; */ 
// Now truncate 
x &= 0xFFFFFFFFL; // again: don't forget the L suffix 
/* x = `500654080` */ 
+3

Tylko jeden z tych literałów w każdym wyrażeniu musi mieć wartość 'long'. Zobacz odpowiedź @ Petera. –

+0

@Martijn: accept. ale jaka jest odpowiedź 5? –

+0

Wiem, ale myślę, że jest to preferencja stylu. –

5

Wyrażenia 24*60*60*1000*1000 jest typem int nie long Co chcesz jest 24L*60*60*1000*1000 który jest long

To jest to, co masz.

final long x = (24*60*60*1000*1000) & 0xFFFFFFFF; 
final long y = (24*60*60*1000) & 0xFFFFFFFF; 
System.out.println(x/y); 

co chcesz to

final long x = 24L*60*60*1000*1000; 
final long y = 24L*60*60*1000; 
System.out.println(x/y); 
+0

Aby być jednoznacznym, zawsze możesz zrobić "1L * 24 * 60 * 60 * 1000 * 1000". –

+0

W takim przypadku możesz wykonać '(długi) 24 * 60 * 60 * 1000 * 1000' –

+0

Kiedy nastąpi int-> długa promocja? Dla 24 lub pełnego (zgłoszonego) wyniku? –

1

24*60*60*1000*1000 jest zbyt duża, aby zmieścić się w int i przelewów.

1

Tricky one!

Problem polega na tym, że 24, 60 i 1000 to literał Java ints. Zanim wartości zostaną przypisane do x i y, zostaną obcięte, aby pasowały do ​​wartości int. Wypróbuj

System.out.print(x + ", " + y); 

, aby zobaczyć dokładnie, co mam na myśli. Szybka poprawka jest aby dokonać literały w długich wartościach tak:

public class LongDiv{ 
public static void main(String [] args){ 

    final long x = 24l*60l*60l*1000l*1000l; 
    final long y = 24l*60l*60l*1000l; 
    System.out.println(x/y); 
} 
} 
+0

Pobity do ponczu! Nie tak trudne, jak myślałem, chyba :) – Eric

2

odlewania (wymuszenie) do długich prac w przypadku wartości dosłownych dla prawego argumentu; ale problem nadal występuje w przypadku przypisywania jeden długi zmiennej do drugiej, jak w podanym przykładzie poniżej:

package utils; 

public class Utils { 

    public static void main(String ... clps){ 
     Utils.longDivision(); 
     Utils.doubleDivision(); 
    } 

    private static void doubleDivision(){ 
     double x=new Long("54321").doubleValue(); 
     double y=new Long("12345").doubleValue(); 
     double difference=x - y; 
     double percentage=(difference/x)*100.00; 
     System.out.println("\nDouble Division ==> X : "+x+" ; Y : "+y+" ; Difference : "+difference+" ; percentage : "+percentage+"\n"); 
    } 

    private static void longDivision(){ 
     long x=new Long("54321").longValue(); 
     long y=new Long("12345").longValue(); 
     long difference=x - y; 
     long percentage=(difference/x)*100L; 
     System.out.println("\nLong Division ==> X : "+x+" ; Y : "+y+" ; Difference : "+difference+" ; percentage : "+percentage+"\n"); 
    } 

} 

Jedynym sposobem mogę dostać właściwą odpowiedź jest poprzez przekształcenie podział tęskni do podziału podwójnej. To bardzo dziwne, dlaczego podział długich zachowuje się w tak tajemniczy sposób.

longDivision podaje odpowiedź jako zero, natomiast doubleDivision podaje poprawną odpowiedź.

Mam nadzieję, że to pomoże innym, którzy napotkali podobne problemy ...

Powiązane problemy