INT_MIN-1 è un underflow o un overflow?


10

Mi sembra di ricordare che lo stavo leggendo

  • underflowsignifica che hai una grandezza troppo piccola che non può più essere presentata in un tipo
  • overflowsignifica che hai una grandezza troppo grande che non può più essere presentata in un tipo

Tuttavia, in pratica, percepisco che i termini sono usati in modo tale

  • underflowsignifica che hai un valore troppo piccolo che non può più essere presentato in un tipo
  • overflowsignifica che hai un valore troppo grande che non può più essere presentato in un tipo

Qual è il significato corretto da usare qui? I termini sono definiti in modo diverso per tipi interi e in virgola mobile?


2
In generale, il termine "underflow" sembra essere riservato per l'aritmetica in virgola mobile. Con gli interi, di solito dico "overflow" indipendentemente dal fatto che sia INT_MIN - 1oINT_MAX + 1
Charles Salvia il

Risposte:


15

Non riesco davvero a trovare una fonte "autorevole" su questo argomento, soprattutto perché questa è probabilmente una questione di convenzione e la terminologia è spesso molto incoerente. Ma il seguente estratto del " Secure Coding in C e C ++ " di Robert Seacord riassume la mia comprensione della situazione:

Si verifica un overflow di numeri interi quando un numero intero viene aumentato oltre il valore massimo o diminuito oltre il valore minimo 3 . Gli overflow di numeri interi sono strettamente correlati alla rappresentazione sottostante.

La nota a piè di pagina continua dicendo:

[3] La riduzione di un numero intero oltre il suo valore minimo viene spesso definita underflow di numero intero , sebbene tecnicamente questo termine si riferisca a una condizione in virgola mobile.

Il motivo per cui lo chiamiamo overflow di numeri interi è perché non c'è abbastanza spazio disponibile nel tipo per rappresentare il valore. In questo senso, è simile a un buffer overflow (tranne che invece di attraversare effettivamente il limite del buffer, di solito mostra un comportamento avvolgente. *) Da questo punto di vista, non vi è alcuna differenza concettuale tra INT_MIN - 1e INT_MAX + 1. In entrambi i casi semplicemente non c'è abbastanza spazio nel inttipo di dati per rappresentare entrambi i valori, quindi quello che abbiamo è un overflow .

Potrebbe anche essere utile notare che nelle architetture del processore x86 e x86_64, il registro dei flag include un bit di overflow . Il bit di overflow viene impostato quando trabocca un'operazione aritmetica di numeri interi con segno. L'espressione INT_MIN - 1imposterà il bit di overflow. (Non esiste un bit "underflow"). Quindi, chiaramente gli ingegneri di AMD e Intel usano il termine "overflow" per descrivere il risultato di un'operazione aritmetica intera che ha troppi bit per adattarsi al tipo di dati, indipendentemente dal fatto che il il valore è numericamente troppo grande o troppo piccolo.


* In effetti, in C, l'overflow di numeri interi con segno è in realtà un comportamento indefinito, ma in altri linguaggi come Java, l'aritmetica del complemento dei due andrà a finire.


6

È un trabocco. Non si verifica un underflow per valori interi.

Un overflow è quando un valore è troppo grande (troppo lontano da zero) per essere rappresentato dal tipo specifico e un underflwo è quando è troppo piccolo (troppo vicino a zero).

Poiché i valori interi più vicini a zero (1 e -1) possono ancora essere rappresentati da qualsiasi variabile intera (supponendo un numero intero con segno con più di un bit), non può verificarsi un underflow.

L' articolo di Wikipedia su underflow ha una descrizione abbastanza chiara:

"Il termine underflow aritmetico (o" underflow in virgola mobile ", o semplicemente" underflow ") è una condizione in un programma per computer che può verificarsi quando il vero risultato di un'operazione in virgola mobile è di entità inferiore (ovvero più vicino a zero) rispetto al valore più piccolo rappresentabile come un normale numero in virgola mobile nel tipo di dati di destinazione. Il underflow può in parte essere considerato come overflow negativo dell'esponente del valore in virgola mobile. "


Può essere utile notare che underflowviene spesso utilizzato specificamente per fare riferimento alla particolare condizione in cui la grandezza di un numero è inferiore a quella del valore non zero possibile più piccolo, ma maggiore della distanza più piccola possibile tra valori diversi da zero - in altri parole, casi in cui i numeri rientrano in quello che l'articolo Wiki chiama "gap insufficiente". Sulle implementazioni conformi IEEE-744, il numero rappresentabile più piccolo equivale alla differenza rappresentabile più piccola tra i numeri, quindi tali underflow non possono verificarsi, ma al di fuori del mondo dei PC, non tutti i sistemi sono conformi IEEE.
supercat

2

Nella matematica dei numeri interi, l'overflow si riferisce a valori sia troppo grandi che troppo piccoli. In virgola mobile, overflow si riferisce a un esponente troppo grande e underflow si riferisce a un esponente troppo piccolo.

In effetti, per i tipi interi , le CPU non hanno modo di distinguere tra overflow e underflow. Prendi la seguente aggiunta a 16 bit:

  0x8000 (unsigned 32768, or signed -32767)
+ 0xFFFF (unsigned 65535, or signed -1)
--------
  0x7FFF (32767, the carried '1' is lost)

Il flag di overflow nella CPU, ovviamente, verrebbe impostato dopo questa aggiunta. Utilizzando la matematica firmata, il risultato è troppo piccolo (-32768). Utilizzando la matematica senza segno, il risultato è troppo grande (0x17FFF). Poiché la matematica del complemento di 2 è identica per i tipi con segno e senza segno, overflowè costretta a significare valori sia troppo grandi che troppo piccoli.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.