2013-02-19 10 views
9

Minęło dużo czasu, odkąd ostatni zaprogramowany na poziomie bitów i bajtów i chciał potwierdzić coś wydaje mi się, pamiętam z tamtych czasów:dodając dwa podpisane lub niepodpisane liczby całkowite

Powiedz, mam dwie liczby całkowite o jednakowej długości (1, 2, 4, 8 bajtów, to nie ma znaczenia), i dodaję je: czy bitowy wynik sumy różni się, jeśli są podpisane lub niepodpisane. Innymi słowy: niezależnie od tego, czy są to liczby całkowite z podpisem czy bez znaku, czy bity będą takie same?

Moja intuicja i słaba pamięć mówią mi, że tak, ale chciałem tylko potwierdzić. Dzięki.

+1

IIRC, chociaż wynik wygląda OK, standard C/C++ mówi, że przepełnienie całkowite skutkuje niezdefiniowanym zachowaniem. ** EDIT **: niepodpisana arytmetyka nie przepełnia się i normalnie postępuje zgodnie z oblewaniem. – nhahtdh

+0

@nhahtdh: dzięki; W porządku. Zrobiłem to za pomocą C++, ponieważ pomyślałem, że będzie to dobra publiczność, ale będę używał tego w innym języku. – Eduardo

+2

http://stackoverflow.com/questions/9024826/how-disastrous-is-integer-overflow-in-c – nhahtdh

Odpowiedz

13

Zakładając, że implementacja używa uzupełnienia 2 jako reprezentacji liczb całkowitych ze znakiem, wyniki będą takie same. W innych reprezentacjach nie będą.

EDIT

Jak zauważył w komentarzach, przepełnienie w podpisanym Ponadto jest niezdefiniowane zachowanie, co oznacza, że ​​nic nie można powiedzieć o wynikach w takim przypadku.

+0

Chciałbym móc dwa razy zagłosować: raz na odpowiedź i drugą za potwierdzenie, że moja pamięć nie jest taka zła :-) – Eduardo

+1

@Eduardo, rozstawię się w drugim głosowaniu. Dobra, krótka, poprawna odpowiedź. – Lindydancer

+3

I przy wywoływaniu UB w dodatku, nie będą one również. – PlasmaHH

4

Wiem, że to już zostało odebrane, ale wszystkie procesory, z którymi kiedykolwiek pracowałem (około tuzin różnych architektur - mam na myśli architekturę, a nie różne smaki) mają tylko jeden typ instrukcji ADD - mogą mieć różne opcje rozmiaru, ale jest to jedna instrukcja. To samo dotyczy odejmowania. Inaczej jest w przypadku mnożenia i dzielenia, które zwykle ma warianty dla podpisu i bez znaku - lub wymagają, aby dane wejściowe były w jakiś sposób "znakowane".

Jedynymi innymi instrukcjami, które rozróżniają podpisane i niepodpisane, są instrukcje warunkowe, np. "Oddział mniejszy niż" będzie miał jeden wariant dla "niepodpisany mniejszy niż" i jeden wariant dla "podpisany mniejszy niż" (z których jeden zwykle nazywany jest czymś innym niż "mniejszy niż", taki jak "poniżej" lub "zestaw do przenoszenia") lub niektóre takie).

+0

Jest to bardzo dobry punkt - nawet jeśli standard mówi, że zachowanie jest niezdefiniowane, jest mało prawdopodobne, aby zrobił coś, co nie leży w podstawowej architekturze procesora. To nie jest sposób na C i C++. –

+1

@MarkRansom To naprawdę zależy od kontekstu. Pytanie związane z powyższym nhahtdh pokazuje przykład, w którym interweniuje kompilator. – Angew

+0

Tak. Oczywiście, mogą istnieć NIEKTÓRE CPU, które mają różne podpisane i niepodpisane instrukcje "dodaj" i "odejmij", nie widziałem jeszcze ani jednego [ani nawet nie słyszałem o jednym]. Specyfikacje C/C++ są pisane przez prawników językowych, którzy muszą zaspokoić wszystkie rodzaje sprzętu WEIRD. To nie znaczy, że tego typu sprzęt będziemy widzieli bardzo często ...;) –