2011-10-14 15 views
19

Sprawdziłem dokument long = int64 ma wahać się więcej niż 900.000.000.000.000dlaczego miałoby to skutkować długim całkowitej przepełnienie

Oto mój kod:

int r = 99; 
long test1 = r*r*r*r*r; 

przy starcie daje mi 919,965,907 zamiast poprawna 9,509,900,499.

kolejny test

long test2 = 99*99*99*99*99; 

ona odmawia skompilować, mówiąc całkowitą przepełnienie.

Ale jeśli mogę to zrobić

long test3 = 10100200300; 

To działa prawidłowo.

Odpowiedz

48

Problemem jest to, że ciąg znaków „99” jest traktowany jako int. Jeśli dodasz "L", potraktuje to jako długi. Aby rozwiązać problem kompilacji:

long test2 = 99L * 99L * 99L * 99L * 99L; 

I naprawić „nieprawidłowy wynik” spowodowanych przez całkowitą przepełnienie:

long r = 99; 
long test1 = r * r * r * r * r; 

Kluczową kwestią jest to, że wyrażenie po prawej stronie „=” jest oceniany przed zadanie zostało wykonane na .

Istnieją inne dosłowne przyrostków może być zainteresowany w:

Type Suffix Example 
uint U or u 100U 
long L or l 100L 
ulong UL or ul 100UL 
float F or f 123.45F 
decimal M or m 123.45M 

@ m.edmonson, chodzi o Twoje pytanie, dlaczego to wychodzi do 919965907. co się dzieje, jest to, że wartość jest „opakowanie” wokół int.MaxValue. Możesz to zobaczyć za pomocą małego programu testowego:

int i = 99; // 99 
i *= 99; // 9801 
i *= 99; // 970299 
i *= 99; // 96059601 
i *= 99; // 919965907  should be 9509900499 but comes out to 919965907 
      //      which is (9509900499 % int.MaxValue) 

long k = 9509900499 % int.MaxValue; 

Co to znaczy "owinąć"? Kiedy przekroczysz int.MaxValue o 1, wartość "powraca" do int.MinValue.

int j = int.MaxValue; 
j++; 

bool isNowMinValue = (j == int.MinValue); // true, the value has "wrapped around" 

To trochę uproszczone; jeśli szukasz "przepełnienia liczby całkowitej", otrzymasz lepsze wyjaśnienie. Warto zrozumieć, jak całkowite (oraz inne typy liczbowe) są reprezentowane w 32 bitach:

http://en.wikipedia.org/wiki/Signed_number_representations

+0

Doskonała odpowiedź - czy możesz wyjaśnić, dlaczego dostaje inny wynik między mnożeniem długim a całkowitym? –

+0

Czy możesz wyjaśnić, co masz na myśli, pakując? A co to ma wspólnego z modułem%? –

+0

Wierzę, że potrzebujesz tylko jednego '99L', reszta zostanie wyrzucona. –

5

jest za pomocą liczby całkowitej mnożenia:

long r = 99; 
long test1 = r*r*r*r*r; 
3

Twój drugi test nie powiedzie się, ponieważ każde 99 jest liczbą całkowitą; zamień go na następujący i skompiluje.

long test2 = 99L * 99L * 99L * 99L * 99L; 

Aby uzyskać szczegółowe informacje, patrz MSDN Long Documentation.

1

Kompilator patrzy na 99 jako liczby całkowite, mimo że końcowy wynik będzie długi.

To zadziała.

long test2 = 99L*99L*99L*99L*99L; 
4

Jako drugi powiedział, ale:

long test2 = 99L * 99 * 99 * 99 * 99; 

To daje poprawny wynik z mniej L wokół :-)

Dzieje się tak, ponieważ pierwszy 99L jest long, więc wszystkie mnożenia są wykonywane w "polu" long, a wszystkie inne liczby całkowite są przed mnożenia wykańczane do long (wyraźnie mnożenie jest zawsze pomiędzy 2 liczbami i jest od lewej do prawej, więc to jest jak (((99L * 99) * 99) * 99) * 99, a każdy "częściowy" wynik jest długi i powoduje, że następny operand ma zostać przekształcony na długi.)

Powiązane problemy