Español | English
rss facebook linkedin Twitter

Comprobando limites

Muchas veces cuando estamos programando, nos cercioramos de que los valores con los que trabajamos no van a producir ningún resultado extraño. Por ejemplo, que el índice con el que recorremos un array no sobrepasa sus límites, que al hacer una división el denominador no sea 0, no calcular el logaritmo de un número negativo o que un puntero no sea null entre muchos otros.
En esta entrada me voy a centrar en la división, aunque también es aplicable a la multiplicación. La comprobación del denominador distinto de 0 es la "clásica" comprobación que todo el mundo realiza, pero no es el único problema que presenta la división de números enteros. Muchas veces se nos olvida que un ordenador no trabaja con una precisión infinita, está relegada a hacer sus cálculos en 8, 16, 32, 64 o más bits por lo que siempre hay un límite y una vez superado tenemos un error de overflow.
Si dividimos un numero entero A entre -1 obtenemos el mismo número A cambiado de signo. Aquí es donde hay que hacer la comprobación ya que esto no es cierto siempre. Si A es el menor número entero, al dividirlo por -1 obtenemos un 0. Veamos un ejemplo, si trabajamos con un procesador de 16 bits, los números enteros van desde -32768 a +32767, si dividimos -32768 entre -1 obtenemos +32768 que provoca un desbordamiento u overflow y nos da como resultado 0. Normalmente estos errores son detectados en tiempo de ejecución y dependiendo del lenguaje, el runtime y/o las opciones de compilación la ejecución del programa no se detiene sino que continúa ejecutándose con un dato erróneo. En java (Long.MIN_VALUE/-1) devuelve Long.MIN_VALUE mientras que en C (MININT/-1) da 0, en otros lenguajes no he comprobado pero los resultados serán similarmente dispares.
Esto puede llevar a resultados catastróficos si tenemos dos aplicaciones que deban compartir datos y cada una este escrita en un lenguaje distinto. Al calcular un hash de un valor, o un CRC de un fichero, arrojarán valores distintos en una y otra.
Además la expresión la podemos pasar como parámetro a un cgi, éste se parará si tiene activado el OverFlowChecking que en algunos lenguajes está activo por defecto.


Eduardo Morrás
S21sec e-crime

2 comentarios:

Lobosoft dijo...

Buenas.

Es el caso, por ejemplo, de .NET y C#. Si hacemos un

int valor = int.MinValue / -1;

obtendremos una excepción por el OverFlowChecking habilitado. En cualquier caso, es cierto que ne muchas ocasiones se dejan de lado validaciones de este tipo que, no por menos obvias, son menos importantes.

Un saludo.

S21sec labs dijo...

Desconocia el resultado en .NET y C#.
Hay metodos/herramientas automaticos (y gratuitos) para comprobar los valores que hacen que una expresion matematica nos pueda dar problemas. Afortunadamente cada vez mas lenguajes de programacion incluyen manejo de excepciones y la filosofia de programacion "Prefiero pedir perdon a pedir permiso" que permiten olvidarnos de las validaciones y simplemente corregir el error cuando ya ha ocurrido.


(+34 902 222 521)


24 horas / 7 días a la semana



© Copyright S21sec 2013 - Todos los derechos reservados


login