INT_MIN-1 è un underflow o un overflow?

10

Mi sembra di ricordare che stavo leggendo quello

  • underflow significa che hai una magnitudine troppo piccola che non può più essere presentata in un tipo
  • overflow significa che hai una magnitudine troppo grande che non può essere più presentata in un tipo

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

  • underflow significa che hai un valore troppo piccolo che non può più essere presentato in un tipo
  • overflow significa 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 i tipi integer e floating point?

    
posta Johannes Schaub - litb 31.12.2010 - 15:16
fonte

3 risposte

14

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

An integer overflow occurs when an integer is increased beyond its maximum value or decreased beyond its minimum value3. Integer overflows are closely related to the underlying representation.

La nota continua a dire:

[3] Decreasing an integer beyond its minimum value is often referred to as an integer underflow, although technically this term refers to a floating point condition.

Il motivo per cui chiamiamo un intero overflow è perché non c'è abbastanza spazio disponibile nel tipo per rappresentare il valore. In questo senso, è simile a un buffer overflow (eccetto piuttosto che attraversare effettivamente il limite del buffer, di solito mostra un comportamento wrap-around. *) Da questa prospettiva, non c'è alcuna differenza concettuale tra INT_MIN - 1 e INT_MAX + 1 . In entrambi i casi semplicemente non c'è abbastanza spazio nel tipo di dati int per rappresentare entrambi i valori, quindi quello che abbiamo è un overflow .

Potrebbe anche essere utile notare che nelle architetture dei processori x86 e x86_64, il registro flags include un bit overflow . Il bit di overflow viene impostato quando si verifica un overflow di un'operazione aritmetica con numero intero con segno. L'espressione INT_MIN - 1 imposterà il bit di overflow. (Non c'è 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 valore è numericamente troppo grande o troppo piccolo.


* Infatti, in C, l'overflow dei numeri interi con segno è in realtà un comportamento non definito, ma in altri linguaggi come Java, l'aritmetica del complemento a due si avvolge.

    
risposta data 31.12.2010 - 16:03
fonte
6

È un overflow. Un underflow non si verifica per i valori interi.

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

Poiché i valori interi più vicini a zero (1 e -1) possono ancora essere rappresentati da qualsiasi variabile intera (assumendo 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:

"The term arithmetic underflow (or "floating point underflow", or just "underflow") is a condition in a computer program that can occur when the true result of a floating point operation is smaller in magnitude (that is, closer to zero) than the smallest value representable as a normal floating point number in the target datatype. Underflow can in part be regarded as negative overflow of the exponent of the floating point value."

    
risposta data 31.12.2010 - 16:56
fonte
2

In matematica intera, l'overflow si riferisce a valori troppo grandi e troppo piccoli. In virgola mobile, l'overflow si riferisce a un esponente troppo grande e il 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, viene impostato dopo questo add. Usando la matematica firmata, il risultato è troppo piccolo (-32768). Usando la matematica non firmata, il risultato è troppo grande (0x17FFF). Poiché la matematica del complemento a 2 è identica per i tipi con segno e senza segno, overflow è obbligato a significare valori troppo grandi e troppo piccoli.

    
risposta data 31.12.2010 - 16:11
fonte

Leggi altre domande sui tag