2012-02-08 11 views
15

Co będzie zawierać unsigned int podczas przepełnienia? Aby być konkretnym, chcę wykonać mnożenie z dwoma unsigned int s: co będzie w unsigned int po zakończeniu mnożenia?Przepełnienie niepodpisane Int

unsigned int someint = 253473829*13482018273; 
+0

To wydaje się być duplikatem http://stackoverflow.com/questions/199333/best-way-to-detect-integer-overflow-in-c-c-c –

+1

Dlaczego nie spróbować i zobaczyć, co otrzymasz? Ogólnie rzecz biorąc, gdy niepodpisana liczba int przepełni się, przechodzi do zera. Tak więc 'UINT_MAX + 5' przewraca się i staje się 4. –

+0

Byłaby to różnica między maksymalną wartością uint a wartością, która byłaby wartością przepełnienia. Pozwala to uprościć. Powiedzmy, że max uint ma wartość 5. Chcesz dodać 2 * 4, więc ta wartość końcowa 3 zamiast 8. –

Odpowiedz

22

unsigned Numery nie mogą być przepełnione, ale zamiast tego zawijaj za pomocą właściwości modulo.

Na przykład, gdy unsigned int ma 32 bity, wynikiem będzie: (a * b) mod 2^32.


Jak CharlesBailey podkreślił 253473829*13482018273 może wykorzystać podpisaną mnożenie przed przeliczone, a więc powinny być jawne o unsigned przed mnożeniem:

unsigned int someint = 253473829U * 13482018273U; 
+0

jest częścią standardu? –

+2

@Zhenya Tak, zarówno w C jak i C++. – Pubby

+0

@Zhenya - Czy to ma znaczenie? Odpowiedź jest w 100% prawidłowa. Jest to bardziej techniczny sposób powiedzenia, że ​​UINT_MAX + 5 to 4. To prawdopodobnie pozostałoby prawdziwe w obu językach .NET i Java. Przynajmniej w przypadku .NET NaN jest ograniczone do typów takich jak double, gdzie wartość (przez większość czasu) nie jest dokładnie reprezentowana. –

5

liczba całkowita bez znaku przelewem, w przeciwieństwie do swoich podpisał odpowiednik, wystawy dobrze zdefiniowane zachowanie.

Wartości zasadniczo "zawijają się". Jest bezpieczny i często używany do odliczania lub funkcji mieszania/modowania.

+3

Unsigned nie przepełnia się –

+1

Chciałem to porównać, aby spróbować wyjaśnić, odnosząc się do czegoś podobnego. Później zakwalifikowałem moje oświadczenie za pomocą owijki. Ah techniczne. – evandrix

-3

Prawdopodobnie zależy to trochę od kompilatora. Miałem błędy takie jak te lata temu, a czasami dostałeś błąd runtime, innym razem w zasadzie "zawijał" z powrotem do naprawdę małej liczby, która byłaby wynikiem odcięcia bitów najwyższego poziomu i pozostawiania reszty, tj. Jeśli jest 32 bit unsigned int, a wynikiem twojego mnożenia byłaby liczba 34-bitowa, odetnę 2-bitowe najwyższe wartości i dostaniesz resztę. Prawdopodobnie musiałbyś wypróbować to na swoim kompilatorze, aby zobaczyć dokładnie, co otrzymujesz, co może nie być tym samym, co otrzymasz za pomocą innego kompilatora, zwłaszcza jeśli przepełnienie występuje w środku wyrażenia, w którym wynik końcowy jest w obrębie zakres unsigned int.

+0

** Unsigned ** overflow nie zależy od kompilatora, jest standaryzowany, aby mieć semantykę wrap-around. Jest to tylko ** podpisane ** przepełnienie, które prowadzi do niezdefiniowanych wartości i dlatego może zależeć od kompilatora. – cmaster