INT_MIN-1 é um underflow ou estouro?

10

Eu me lembro que estava lendo isso

  • underflowsignifica que você tem uma magnitude muito pequena que não pode mais ser apresentada em um tipo
  • overflowsignifica que você tem uma magnitude muito grande que não pode mais ser apresentada em um tipo

No entanto, na prática, percebo que os termos são usados ​​de tal maneira que

  • underflowsignifica que você tem um valor muito pequeno que não pode mais ser apresentado em um tipo
  • overflowsignifica que você tem um valor muito grande que não pode mais ser apresentado em um tipo

Qual é o significado correto para usar aqui? Os termos são definidos de maneira diferente para os tipos inteiro e ponto flutuante?

Johannes Schaub - litb
fonte
2
Geralmente, o termo "subfluxo" parece ser reservado para aritmética de ponto flutuante. Com números inteiros, costumo dizer "estouro", independentemente de ser INT_MIN - 1ou nãoINT_MAX + 1
Charles Salvia

Respostas:

15

Não consigo realmente encontrar uma fonte "autorizada" sobre esse assunto, principalmente porque isso é provavelmente uma questão de convenção, e a terminologia geralmente é muito inconsistente. Mas, o trecho a seguir de " Secure Coding in C and C ++ " de Robert Seacord resume minha compreensão da situação:

Um estouro de número inteiro ocorre quando um número inteiro é aumentado além do seu valor máximo ou diminuído além do seu valor mínimo 3 . Estouros de número inteiro estão intimamente relacionados à representação subjacente.

A nota de rodapé continua dizendo:

[3] Diminuir um número inteiro além do seu valor mínimo é geralmente chamado de fluxo insuficiente de números inteiros , embora tecnicamente esse termo se refira a uma condição de ponto flutuante.

O motivo pelo qual chamamos de excesso de número inteiro é porque simplesmente não há espaço suficiente disponível no tipo para representar o valor. Nesse sentido, é semelhante a um estouro de buffer (exceto que, em vez de realmente cruzar o limite do buffer, geralmente exibe um comportamento envolvente. *) Nessa perspectiva, não há diferença conceitual entre INT_MIN - 1e INT_MAX + 1. Nos dois casos, simplesmente não há espaço suficiente no inttipo de dados para representar os dois valores - portanto, o que temos é um estouro .

Também pode ser útil observar que nas arquiteturas dos processadores x86 e x86_64, o registro de sinalizadores inclui um bit de estouro . O bit de estouro é definido quando uma operação aritmética de número inteiro assinado transborda. A expressão INT_MIN - 1definirá o bit de estouro. (Não há um bit "underflow"). Tão claramente, os engenheiros da AMD e da Intel usam o termo "overflow" para descrever o resultado de uma operação aritmética inteira que possui muitos bits para caber no tipo de dados, independentemente de o o valor é numericamente muito grande ou muito pequeno.


* De fato, em C, o excesso de número inteiro assinado é na verdade um comportamento indefinido, mas em outras linguagens como Java, a aritmética de complemento dos dois será contornada.

Charles Salvia
fonte
6

É um estouro. Um fluxo insuficiente não ocorre para valores inteiros.

Um estouro é quando um valor é muito grande (muito longe de zero) para ser representado pelo tipo específico, e um fluxo insuficiente é quando é muito pequeno (muito próximo de zero).

Como os valores inteiros mais próximos de zero (1 e -1) ainda podem ser representados por qualquer variável inteira (assumindo um número inteiro assinado com mais de um bit), um subfluxo não pode ocorrer.

O artigo da Wikipedia sobre subfluxo tem uma descrição bastante clara:

"O termo underflow aritmético (ou" underflow de ponto flutuante "ou apenas" underflow ") é uma condição em um programa de computador que pode ocorrer quando o verdadeiro resultado de uma operação de ponto flutuante é menor em magnitude (ou seja, mais próximo de zero) do que o menor valor representável como um número de ponto flutuante normal no tipo de dados de destino. O subfluxo pode, em parte, ser considerado como excesso negativo do expoente do valor do ponto flutuante. "

Guffa
fonte
Pode ser útil observar que underflowgeralmente é usado especificamente para se referir à condição específica em que a magnitude de um número é menor que a do menor valor possível, diferente de zero, mas maior que a menor distância possível entre valores diferentes de zero - em outras palavras, casos em que os números se enquadram no que o artigo da Wiki chama de "lacuna de fluxo insuficiente". Em implementações compatíveis com IEEE-744, o menor número representável é igual à menor diferença representável entre números, portanto, essas subfluxos não podem ocorrer, mas fora do mundo dos PCs, nem todos os sistemas são compatíveis com IEEE.
30812
2

Em matemática inteira, o excesso refere-se a valores muito grandes e muito pequenos. No ponto flutuante, o estouro se refere a um expoente muito grande e o estouro se refere a um expoente muito pequeno.

De fato, para tipos inteiros , as CPUs não têm como diferenciar entre estouro e estouro. Faça o seguinte acréscimo de 16 bits:

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

O sinalizador de estouro na CPU seria, é claro, definido após esse acréscimo. Usando matemática assinada, o resultado é muito pequeno (-32768). Usando matemática não assinada, o resultado é muito grande (0x17FFF). Como a matemática do complemento de 2 é idêntica para os tipos assinado e não assinado, overflowé forçada a significar valores muito grandes e muito pequenos.

Nota para pensar em um nome
fonte