Remove ads
condición en aritmética informática que se da cuando un cálculo produce un resultado que es mayor en magnitud que el que puede representar una ubicación de almacenamiento determinada De Wikipedia, la enciclopedia libre
En programación, se produce un desbordamiento de enteros cuando una operación aritmética intenta crear un valor numérico que está fuera del rango que puede representarse con un número dado de dígitos, ya sea mayor que el máximo o menor que el mínimo valor representable.
El resultado más común de un desbordamiento es que se almacenan los dígitos representables menos significativos del resultado; se dice que el resultado se envuelve alrededor del máximo (es decir, el resultado obtenido se corresponde a aplicar el módulo del máximo admisible, una potencia entera de la base interna de cálculo, generalmente dos en las computadoras modernas, pero a veces diez u otro número).
Una condición de desbordamiento puede dar resultados que conducen a un comportamiento no deseado. En particular, si no se ha anticipado esta posibilidad, el desbordamiento puede comprometer la fiabilidad de un programa y su seguridad.
Para algunas aplicaciones, como los temporizadores y los relojes, puede ser conveniente ajustar el desbordamiento. El estándar C11 indica que para enteros sin signo, el ajuste de módulo es el comportamiento definido y el término desbordamiento nunca se aplica: "un cálculo que involucre operandos sin signo nunca puede desbordarse".[1]
En algunos procesadores como las tarjetas gráficas (GPUs) y procesadores digitales de señales (DSPs) que soportan aritmética de saturación, los resultados desbordados se "fijan", es decir, se establecen en el valor mínimo o máximo del rango representable, en lugar de modularse con respecto al máximo.
La arquitectura interna de un procesador determina el rango de valores que se pueden representar en sus registros. Aunque la gran mayoría de las computadoras pueden realizar aritmética de precisión múltiple con los operandos de la memoria, lo que permite que los números sean arbitrariamente largos y se eviten los desbordamientos, el ancho del registro limita el tamaño de los números individuales que pueden operarse (por ejemplo, sumar o restar) usando una instrucción única por operación. Los anchos de registro binarios típicos para enteros sin signo incluyen:
Cuando una operación aritmética produce un resultado mayor que el máximo anterior para un entero de N bits, un desbordamiento reduce el resultado al módulo de la N-ésima potencia de 2, reteniendo solo los bits menos significativos del resultado y provocando una vuelta total.
En particular, multiplicar o sumar dos enteros puede resultar en un valor que es inesperadamente pequeño, y restar de un entero pequeño puede causar un ajuste a un valor positivo grande (por ejemplo, la suma de enteros de 8 bits 255 + 2 da como resultado 1, que es 257 mod 28 y, de manera similar, la resta 0 - 1 da como resultado 255, una representación complemento a dos de −1).
Dicha envolvente puede causar problemas de seguridad: si se utiliza un valor desbordado como el número de bytes para asignar a un búfer, el búfer se asignará de forma inesperadamente pequeña, lo que podría provocar un desbordamiento del búfer que, dependiendo de su uso, podría a su vez causa la ejecución de código arbitrario.
Si la variable es del tipo entero con signo, un programa puede suponer que una variable siempre contiene un valor positivo. Un desbordamiento de enteros puede hacer que el valor se ajuste y se vuelva negativo, lo que viola la suposición del programa y puede conducir a un comportamiento inesperado (por ejemplo, la adición de enteros de 8 bits de 127 + 1 da como resultado −128, un complemento de dos de 128). Una solución para este problema en particular es usar tipos de enteros sin signo para los valores que un programa espera y asume que nunca serán negativos.
La mayoría de las computadoras tienen dos indicadores del procesador dedicados para verificar las condiciones de desbordamiento.
La bandera de acarreo se activa cuando el resultado de una suma o resta, considerando los operandos y el resultado como números sin signo, no cabe en el número dado de bits. Esto indica un desbordamiento con un acarreo del bit más significativo. Una operación inmediatamente posterior a "agregar con acarreo" o "restar con préstamo" usaría el contenido de este indicador para modificar un registro o una ubicación de memoria que contenga la parte superior de un valor de varias palabras.
La bandera de desbordamiento también se activa cuando el resultado de una operación en números con signo no tiene el signo que se podría predecir a partir de los signos de los operandos, por ejemplo, un resultado negativo al sumar dos números positivos. Esto indica que se ha producido un desbordamiento y que el resultado presentado (el complemento a dos), no coincide con el resultado verdadero, que no cabría en el número dado de bits.
Para un tipo sin signo, cuando el resultado ideal de una operación está fuera del rango de los tipos representables y el resultado devuelto se obtiene mediante ajuste, entonces este evento se define comúnmente como un desbordamiento.
En contraste, el estándar C11 define que este evento no es un desbordamiento y establece que "un cálculo que involucre operandos sin signo nunca puede desbordarse".[1]
Cuando el resultado ideal de una operación de enteros está fuera del rango de los tipos representables y el resultado devuelto se obtiene mediante fijación, entonces este evento se define comúnmente como una saturación.
El uso varía según si una saturación es o no un desbordamiento. Para eliminar esta ambigüedad, pueden usarse los términos desbordamiento[2] y saturación.[3]
El término subdesbordamiento se usa más comúnmente para las matemáticas de punto flotante y no para la aritmética de enteros. Sin embargo, se pueden encontrar muchas referencias a este concepto para enteros.[4][5][6][7][8] Cuando se utiliza el término de subdesbordamiento de un entero, significa que el resultado ideal estaba más cercano a menos infinito, que el valor representable del tipo de salida más cercano a menos infinito.
Cuando se utiliza el término subdesbordamiento entero, puede incluir todos los tipos de desbordamientos o solo los casos en los que el resultado ideal queda más cercano al infinito positivo que el valor representable del tipo de salida más cercano al infinito positivo.
Cuando el resultado ideal de una operación no es un entero exacto, el significado de desbordamiento puede ser ambiguo en los casos límite.
Considérese el caso donde el resultado teórico tiene un valor 127.25 y el valor máximo representable del tipo de salida es 127. Si el desbordamiento se define como el valor ideal que está fuera del rango representable del tipo de salida, este caso se clasificaría como un desbordamiento.
Para las operaciones que tienen un comportamiento de redondeo bien definido, la clasificación de desbordamiento puede necesitar posponerse hasta que se aplique el redondeo.
El estándar C11[1] define que las conversiones de punto flotante a entero deben redondearse hacia cero. Si se usa C para convertir el valor de coma flotante 127.25 a entero, entonces se debe aplicar primero el redondeo para obtener una salida de entero ideal de 127. Dado que el entero redondeado está en el rango de salidas, el estándar C no clasificaría esta conversión como un desbordamiento.
Lenguaje | Entero sin signo |
Entero con signo |
---|---|---|
Ada | Se modula según tipo | raise Constraint_Error |
C/C++ | Módulo potencia de 2 | Comportamiento indefinido |
C# | Módulo potencia de 2 en contexto sin comprobación; System.OverflowException se plantea en contexto comprobado[9] | |
Java | N/A | Módulo potencia de 2 |
JavaScript | Todos los números tienen formato en coma flotante de doble precisión | |
MATLAB | Los enteros incorporados se saturan. Enteros de punto fijo configurables para desbordar o saturarse | |
Python 2 | N/A | Convierte a long, entero largo |
Seed7 | N/A | Mensaje raise OVERFLOW_ERROR[10] |
Scheme | N/A | Convierte a bigNum |
Simulink | Configurable para desbordamiento o saturación | |
Smalltalk | N/A | Convierte a LargeInteger (entero largo) |
Swift | Causa error a menos que use operadores de desbordamiento especiales.[11] | |
Hay varios métodos de manejo de desbordamiento:
Los lenguajes de programación implementan varios métodos de mitigación contra un desbordamiento accidental: Ada, Seed7 (y ciertas variantes de lenguajes funcionales), desencadenan una condición de excepción en el desbordamiento, mientras que Python (desde la versión 2.4) convierte a la perfección la representación interna del número para que coincida con su crecimiento, transformándolo a long
, cuya capacidad solo está limitada por la memoria disponible.[12]
La implementación de la detección de desbordamiento en tiempo de ejecución UBSan
también está disponible para los compiladores de C.
En idiomas con soporte nativo para precisión arbitraria y seguridad de tipos (como Python o Common Lisp), los números se promueven a un tamaño más grande automáticamente cuando se producen desbordamientos, o se lanzan excepciones (condiciones señaladas) cuando existe una restricción de rango. El uso de dichos idiomas puede ser útil para mitigar este problema. Sin embargo, en algunos de estos lenguajes, las situaciones de rebosamiento de un entero son todavía posibles. Un ejemplo es la optimización explícita de una ruta de código que el gestor de tareas considera un cuello de botella. En el caso de Common Lisp, esto es posible mediante el uso de una declaración explícita para anotar una variable a una palabra de tamaño de máquina (fixnum)[13] y bajando el nivel de seguridad de tipo a cero[14] para un bloque de código particular.[15][16][17][18]
En Java 8, hay métodos para controlar el rebosamiento, por ejemplo, como Math.addExact(int, int), que arrojarán ArithmeticException en caso de desbordamiento.
El Equipo de Respuesta ante Emergencias Informáticas (CERT) desarrolló el modelo entero As-Infinitly Ranged (AIR), un mecanismo en gran medida automatizado para eliminar el desbordamiento y el truncado de enteros en C/C++ mediante el manejo de errores en tiempo de ejecución.[19]
En computación gráfica o procesamiento de señales, es típico trabajar con datos que van de 0 a 1 o de −1 a 1. Un ejemplo de esto es una imagen en escala de grises, donde 0 representa negro, 1 representa blanco y los valores intermedios representan distintos tonos de gris. Una operación que se podría querer realizar es iluminar la imagen multiplicando cada píxel por una constante. La aritmética de saturación permite simplemente multiplicar ciegamente cada píxel por esa constante sin preocuparse por el desbordamiento, simplemente por mantener un resultado razonable de que todos estos píxeles mayores que 1 (es decir, "más brillantes que el blanco") se vuelven blancos; y todos los valores "más oscuros que el negro", simplemente se vuelven negros.
El desbordamiento aritmético no anticipado es una causa bastante común de errores de programación. Dichos errores de desbordamiento pueden ser difíciles de descubrir y diagnosticar porque pueden manifestarse solo para conjuntos de datos de entrada muy grandes, que es menos probable que se usen en las pruebas de validación.
Si se toma la media aritmética de dos números al sumarlos y se divide por dos, como se hace en muchos algoritmos de búsqueda, se produce un error si la suma (aunque no la media resultante) es demasiado grande para ser representada y, por lo tanto, se desborda.[20]
Seamless Wikipedia browsing. On steroids.
Every time you click a link to Wikipedia, Wiktionary or Wikiquote in your browser's search results, it will show the modern Wikiwand interface.
Wikiwand extension is a five stars, simple, with minimum permission required to keep your browsing private, safe and transparent.