Desbordamiento de enteros

Manejo del desbordamiento de enteros en varios lenguajes de programación
Lenguaje Entero sin signo Entero con signo
Ada módulo el módulo del tipo raise Constraint_Error
C/C++ módulo potencia de dos comportamiento indefinido
C# módulo potencia de 2 en contexto no comprobado; System.OverflowException se eleva en contexto comprobado
Java N/A potencias modulares de dos
JavaScript todos los números son de dobleprecisión de punto flotante excepto el nuevo BigInt
MATLAB Los enteros construidos saturan. Fijo-enteros de punto fijo configurables para envolver o saturar
Python 2 N/A convertir a tipo largo (bigint)
Seed7 N/A raise OVERFLOW_ERROR
Scheme N/A convertir a bigNum
Simulink configurable para envolver o saturar
Smalltalk N/A convertir a LargeInteger
Swift Causa error a menos que se utilicen operadores especiales de desbordamiento.

DetecciónEdit

La implementación de detección de desbordamiento en tiempo de ejecución UBSan está disponible para los compiladores de C.

En Java 8, hay métodos sobrecargados, por ejemplo como Math.addExact(int, int), que lanzarán ArithmeticException en caso de desbordamiento.

El equipo de respuesta a emergencias informáticas (CERT) desarrolló el modelo de enteros As-if Infinitely Ranged (AIR), un mecanismo en gran medida automatizado para eliminar el desbordamiento de enteros y el truncamiento en C/C++ utilizando el manejo de errores en tiempo de ejecución.

AvoidanceEdit

Al asignar variables con tipos de datos que son lo suficientemente grandes como para contener todos los valores que posiblemente pueden ser calculados y almacenados en ellos, siempre es posible evitar el desbordamiento. Incluso cuando el espacio disponible o los tipos de datos fijos proporcionados por un lenguaje o entorno de programación son demasiado limitados para permitir la asignación defensiva de variables con tamaños generosos, ordenando cuidadosamente las operaciones y comprobando los operandos de antemano, a menudo es posible garantizar a priori que el resultado nunca será mayor de lo que puede almacenarse. Las herramientas de análisis estático, la verificación formal y las técnicas de diseño por contrato pueden usarse para asegurar con mayor confianza y solidez que no puede producirse accidentalmente un desbordamiento.

HandlingEdit

Si se anticipa que puede producirse un desbordamiento, entonces pueden insertarse pruebas en el programa para detectar cuando ocurre, o está a punto de ocurrir, y hacer otro procesamiento para mitigarlo. Por ejemplo, si un resultado importante calculado a partir de la entrada del usuario se desborda, el programa puede detenerse, rechazar la entrada, y tal vez pedir al usuario una entrada diferente, en lugar de que el programa continúe con la entrada no válida desbordada y probablemente funcione mal como consecuencia. Este proceso completo puede ser automatizado: es posible sintetizar automáticamente un manejador para un desbordamiento de enteros, donde el manejador es, por ejemplo, una salida limpia.

Las CPUs generalmente tienen una forma de detectar esto para soportar la adición de números más grandes que su tamaño de registro, normalmente utilizando un bit de estado; la técnica se llama aritmética de precisión múltiple.Así, es posible sumar dos números cada uno de dos bytes de ancho usando sólo una adición de bytes en pasos: primero sumar los bytes bajos y luego sumar los bytes altos, pero si es necesario llevar a cabo de los bytes bajos esto es desbordamiento aritmético de la adición de bytes y se hace necesario detectar e incrementar la suma de los bytes altos.

El manejo de un posible desbordamiento de un cálculo puede a veces presentar una opción entre realizar una comprobación antes del cálculo real (para determinar si se va a producir o no el desbordamiento), o después de él (para considerar si es probable que se produzca o no en base al valor resultante). Hay que tener cuidado con esta última opción. En primer lugar, porque puede no ser un método de detección fiable (por ejemplo, una suma no tiene por qué dar lugar a un valor inferior). En segundo lugar, porque la aparición del desbordamiento en sí mismo puede ser en algunos casos un comportamiento indefinido. En el lenguaje de programación C, el desbordamiento de los tipos enteros sin signo resulta en una envoltura, sin embargo, el desbordamiento de los tipos enteros con signo es un comportamiento indefinido; en consecuencia, un compilador de C es libre de asumir que el programador se ha asegurado de que el desbordamiento con signo no puede ocurrir y, por lo tanto, puede optimizar silenciosamente cualquier comprobación posterior al cálculo que implique la comprobación del resultado para detectarlo sin dar al programador ninguna advertencia de que esto se ha hecho. Por tanto, es aconsejable preferir siempre implementar las comprobaciones antes de los cálculos y no después de ellos.

Propagación explícitaEditar

si un valor es demasiado grande para ser almacenado se le puede asignar un valor especial que indique que se ha producido un desbordamiento y luego hacer que todas las operaciones sucesivas devuelvan este valor de bandera. Estos valores se denominan a veces NaN, por «not a number». Esto es útil para que el problema se pueda comprobar una vez al final de un cálculo largo en lugar de después de cada paso. Esto es a menudo apoyado en el hardware de punto flotante llamado FPUs.

Soporte de lenguajes de programaciónEditar

Los lenguajes de programación implementan varios métodos de mitigación contra un desbordamiento accidental: Ada, Seed7 (y ciertas variantes de lenguajes funcionales), lanzan una condición de excepción en caso de desbordamiento, mientras que Python (desde la versión 2.4) convierte sin problemas la representación interna del número para que coincida con su crecimiento, representándolo finalmente como long – cuya capacidad sólo está limitada por la memoria disponible.

En lenguajes con soporte nativo para aritmética de precisión arbitraria y seguridad de tipos (como Python, Smalltalk o Common Lisp), los números son promovidos a un tamaño mayor automáticamente cuando se producen desbordamientos, o se lanzan excepciones (condiciones señaladas) cuando existe una restricción de rango. El uso de estos lenguajes puede ser útil para mitigar este problema. Sin embargo, en algunos de estos lenguajes, todavía son posibles situaciones en las que puede producirse un desbordamiento de enteros. Un ejemplo es la optimización explícita de una ruta de código que el perfilador 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 el tipo de una variable a una palabra de tamaño de máquina (fixnum) y bajar el nivel de seguridad de tipo a cero para un bloque de código en particular.

En marcado contraste con los lenguajes más antiguos como C, algunos lenguajes más nuevos, como Rust por ejemplo, proporcionan una funcionalidad incorporada que permite una fácil detección y la elección del usuario sobre cómo el desbordamiento debe ser manejado en una base de caso por caso. En Rust, aunque el uso de operadores matemáticos básicos carece naturalmente de tal flexibilidad, los usuarios pueden realizar cálculos alternativamente a través de un conjunto de métodos proporcionados por cada uno de los tipos primitivos enteros. Estos métodos dan a los usuarios varias opciones entre realizar una operación «comprobada» (o «desbordada») (que indica si se ha producido o no el desbordamiento a través del tipo de retorno); una operación «no comprobada»; una operación que realiza la envoltura, o una operación que realiza la saturación en los límites numéricos.

Aritmética saturadaEditar

En los gráficos por ordenador o el procesamiento de señales, es típico trabajar con datos que van de 0 a 1 o de -1 a 1. Por ejemplo, tomemos una imagen en escala de grises en la que el 0 representa el negro, el 1 el blanco y los valores intermedios representan tonos de gris. Una operación que se puede querer realizar es aclarar la imagen multiplicando cada píxel por una constante. La aritmética saturada permite multiplicar ciegamente cada píxel por esa constante sin preocuparse por el desbordamiento, simplemente ateniéndose a un resultado razonable de que todos estos píxeles mayores que 1 (es decir, «más brillante que el blanco») simplemente se convierten en blanco y todos los valores «más oscuros que el negro» simplemente se convierten en negro.

Deja una respuesta

Tu dirección de correo electrónico no será publicada.