2013-02-19 10 views
9

E 'stato un lungo periodo di tempo dall'ultima volta che ho programmato a livello di bit e byte e voluto confermare qualcosa che mi sembra di ricordare di quei giorni:l'aggiunta di due firmato o interi senza segno

Dire che ho due interi di uguale lunghezza (1, 2, 4, 8 byte, non importa) e li aggiungo: il risultato bit-by-bit della somma è diverso se sono firmati o non firmati. In altre parole: indipendentemente dal fatto che siano interi con segno o senza segno, i bit finiranno per essere gli stessi?

La mia intuizione e la mia memoria fragile mi dicono che lo faranno, ma volevo solo confermarlo. Grazie.

+1

IIRC, anche se il risultato sembra OK, lo standard C/C++ dice che l'overflow di interi ha come risultato un comportamento indefinito. ** MODIFICA **: l'aritmetica senza segno non trabocca e segue normalmente il wrap-around. – nhahtdh

+0

@nhahtdh: grazie; va bene. L'ho taggato con C++ perché pensavo che sarebbe stato un buon pubblico a chiederlo, ma lo userò in un'altra lingua. – Eduardo

+2

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

risposta

13

Supponendo che l'implementazione utilizzi il complemento a 2 come rappresentazione di interi con segno, i risultati saranno gli stessi. In altre rappresentazioni, non lo faranno.

EDIT

Come sottolineato nei commenti, troppo pieno oltre firmato è un comportamento indefinito, il che significa che nulla si può dire circa i risultati in questo caso.

+0

Vorrei poter votare due volte: una volta per la risposta e un'altra per confermare che la mia memoria non è così male :-) – Eduardo

+1

@ Eduardo, passo alla seconda votazione. Buona, breve, risposta corretta. – Lindydancer

+3

E quando invocate UB nell'aggiunta, non lo faranno neanche. – PlasmaHH

4

So che è già stata data una risposta, ma tutti i processori con cui ho mai lavorato (circa una dozzina di architetture diverse - e intendo architetture, non di sapori diversi) hanno UN solo tipo di istruzione ADD - potrebbe avere differenti opzioni di dimensioni, ma è l'unica istruzione. Lo stesso vale per sottrarre. È diverso per moltiplicare e dividere, che in genere ha varianti per i segni e i non firmati, oppure per richiedere che l'input sia "regolato dal segno" in qualche modo.

Le uniche altre istruzioni che fanno una distinzione tra firmato e non firmato sono le istruzioni condizionali, ad es. "branch on less than" avrà una variante per "unsigned less than" e una variante per "signed less than" (una delle quali di solito è chiamata qualcosa di diverso da "less than", come "below" o "carry set" o alcuni di questi).

+0

Questo è un ottimo punto: anche se lo standard dice che il comportamento non è definito, è improbabile che faccia qualcosa che l'architettura della CPU sottostante non sia in grado di fare. Non è così che rotolano C e C++. –

+1

@MarkRansom Dipende davvero dal contesto. La domanda collegata da nhahtdh sopra mostra un esempio in cui interviene il compilatore. – Angew

+0

Sì. Naturalmente, ci possono essere ALCUNE CPU che hanno diverse istruzioni firmate e non firmate per "aggiungere" e "sottrarre", devo ancora vederne una [o persino sentirne parlare una]. Le specifiche C/C++ sono scritte da giuristi linguistici che devono soddisfare tutti i tipi di hardware WEIRD. Ciò non significa che vedremo quel tipo di hardware molto spesso ...;) –

Problemi correlati