Idioma | Número inteiro não assinado | Número inteiro assinado |
---|---|---|
Ada | módulo o módulo do tipo | Restrição de erupção |
C/C++ | >modulo power of two | comportamento definido |
C# | modulo power of 2 em contexto não verificado; System.OverflowException é elevado no contexto verificado |
|
Java | N/A | modulo power of two |
JavaScript | todos os números são duplos…ponto flutuante de precisão excepto o novo BigInt | |
MATLAB | Builtin inteiros saturados. Fixo-inteiros de ponto configuráveis para embalar ou saturar | |
Python 2 | N/A | converter para tipo longo (bigint) |
Seed7 | N/A | elevar OVERFLOW_ERROR |
Scheme | N/A | converter para bigNum |
Simulink | configurável para embrulhar ou saturar | |
Smalltalk | N/A | converter para LargeInteger |
Swift | Causa de erro, a menos que utilize operadores especiais de transbordo. |
DetectionEdit
Implementação de detecção de overflow UBSan
está disponível para compiladores C.
Em Java 8, há métodos sobrecarregados, por exemplo, como Math.addExact(int, int)
, que irão lançar ArithmeticException
em caso de overflow.
Equipe de resposta de emergência do computador (CERT) desenvolveu o modelo inteiro As-if Infinitely Ranged (AIR), um mecanismo amplamente automatizado para eliminar o overflow e truncamento de números inteiros em C/C++ usando o tratamento de erros em tempo de execução.
AvoidanceEdit
Alocando variáveis com tipos de dados que são suficientemente grandes para conter todos os valores que possam ser computados e armazenados nelas, é sempre possível evitar o overflow. Mesmo quando o espaço disponível ou os tipos de dados fixos fornecidos por uma linguagem de programação ou ambiente são demasiado limitados para permitir que as variáveis sejam atribuídas defensivamente com tamanhos generosos, ordenando cuidadosamente operações e verificando operandos com antecedência, é muitas vezes possível assegurar a priori que o resultado nunca será maior do que o que pode ser armazenado. Ferramentas de análise estática, verificação formal e projeto por técnicas de contrato podem ser usadas para garantir com mais confiança e robustez que um estouro não possa resultar acidentalmente.
HandlingEdit
Se for previsto que um estouro possa ocorrer, então os testes podem ser inseridos no programa para detectar quando ele acontece, ou está prestes a acontecer, e fazer outro processamento para mitigá-lo. Por exemplo, se um resultado importante for calculado a partir de estouros de input do usuário, o programa pode parar, rejeitar o input e talvez solicitar ao usuário um input diferente, em vez de o programa continuar com o input inválido e provavelmente funcionar mal como conseqüência. Este processo completo pode ser automatizado: é possível sintetizar automaticamente um manipulador para um estouro de número inteiro, onde o manipulador é, por exemplo, uma saída limpa.
CPUs geralmente têm uma maneira de detectar isso para suportar a adição de números maiores que o tamanho do seu registro, tipicamente usando um bit de status; a técnica é chamada de aritmética de precisão múltipla.Assim, é possível adicionar dois números a cada dois bytes de largura usando apenas uma adição de bytes em etapas: primeiro adicione os bytes baixos e depois adicione os bytes altos, mas se for necessário realizar dos bytes baixos isto é um transbordo aritmético da adição de bytes e torna-se necessário detectar e incrementar a soma dos bytes altos.
O tratamento do possível transbordo de um cálculo pode, às vezes, apresentar uma escolha entre realizar uma verificação antes do cálculo real (para determinar se o transbordo vai ou não ocorrer), ou depois dele (para considerar se provavelmente ocorreu ou não com base no valor resultante). Deve-se ter cuidado com esta última escolha. Em primeiro lugar, já que pode não ser um método de detecção confiável (por exemplo, uma adição pode não necessariamente envolver um valor mais baixo). Em segundo lugar, porque a ocorrência de transbordamento em si pode, em alguns casos, ser um comportamento indefinido. Na linguagem de programação C, o transbordamento de tipos inteiros não assinados resulta no embrulho, contudo o transbordamento de tipos inteiros assinados é comportamento indefinido; consequentemente um compilador C é livre de assumir que o programador assegurou que o transbordamento assinado não pode possivelmente ocorrer e assim ele pode silenciosamente otimizar qualquer verificação subseqüente ao cálculo que envolve a verificação do resultado para detectá-lo sem dar ao programador qualquer aviso de que isto foi feito. Assim, é sempre preferível implementar verificações antes dos cálculos e não depois deles.
Propagação explícitaEditar
se um valor for demasiado grande para ser armazenado, pode ser-lhe atribuído um valor especial indicando que ocorreu um overflow e depois ter todas as operações sucessivas a devolver esse valor de flag. Tais valores são às vezes referidos como NaN, para “não um número”. Isto é útil para que o problema possa ser verificado uma vez no final de um longo cálculo e não depois de cada etapa. Isto é frequentemente suportado em hardware de ponto flutuante chamado FPUs.
Linguagem de programação supportEdit
Linguagens de programação implementam vários métodos de mitigação contra um transbordo acidental: Ada, Seed7 (e certas variantes de linguagens funcionais), disparam uma condição de exceção no overflow, enquanto Python (desde 2.4) converte perfeitamente a representação interna do número para corresponder ao seu crescimento, eventualmente representando-o como long
– cuja capacidade é limitada apenas pela memória disponível.
Em linguagens com suporte nativo para aritmética de precisão arbitrária e segurança de tipo (como Python, Smalltalk ou Common Lisp), os números são promovidos a um tamanho maior automaticamente quando ocorrem overflows, ou exceções lançadas (condições sinalizadas) quando existe uma restrição de faixa. O uso de tais linguagens pode, portanto, ser útil para mitigar este problema. No entanto, em alguns desses idiomas, ainda são possíveis situações em que um transbordo de números inteiros pode ocorrer. Um exemplo é a otimização explícita de um caminho de código que é considerado um gargalo pelo profiler. No caso do Common Lisp, isto é possível usando uma declaração explícita para tipificar uma variável para uma palavra de tamanho de máquina (fixnum) e baixar o nível de segurança do tipo para zero para um determinado bloco de código.
Em contraste com línguas mais antigas como C, algumas línguas mais novas, como a Ferrugem, por exemplo, fornecem funcionalidade incorporada que permite a fácil detecção e escolha do usuário sobre como o overflow deve ser tratado caso a caso. Em Rust, enquanto o uso de operadores matemáticos básicos naturalmente carece dessa flexibilidade, os usuários podem alternativamente realizar cálculos através de um conjunto de métodos fornecidos por cada um dos tipos primitivos inteiros. Estes métodos dão aos utilizadores várias escolhas entre executar uma operação ‘verificada’ (ou ‘overflowing’) (que indica se o overflow ocorreu ou não através do tipo de retorno); uma operação ‘desmarcada’; uma operação que executa o embrulho, ou uma operação que executa a saturação nos limites numéricos.
Saturated arithmeticEdit
Em computação gráfica ou processamento de sinais, é típico trabalhar com dados que variam de 0 a 1 ou de -1 a 1. Por exemplo, pegue uma imagem em escala de cinza onde 0 representa preto, 1 representa branco, e os valores intermediários representam tons de cinza. Uma operação que se pode querer suportar é iluminar a imagem, multiplicando cada pixel por uma constante. A aritmética saturada permite multiplicar cegamente cada pixel por aquela constante sem se preocupar com o transbordamento, bastando para isso manter um resultado razoável de que todos esses pixels maiores que 1 (ou seja, “mais brilhante que branco”) se tornem brancos e todos os valores “mais escuros que preto” se tornem pretos.