viernes, 7 de julio de 2017

Dividir no siempre es fácil



Llevo un tiempo sin escribir, y el conocimiento a veces se hace esperar, pero hoy vengo con un nuevo post del Tecnópata Obsoleto donde hablaré de un problema recurrente para el hardware, las matemáticas. No os asustéis, hipoglúcidos, que sólo vamos a hablar de la división y de por qué un programador tiene que tener cuidado a la hora de dividir.

A todos nos han enseñado a dividir de pequeños y lo hacemos de forma automática en muchos casos, sabiendo por ejemplo que, si 2 personas van a comerse una pizza (iba a poner barbacoa, pero puede haber veganos leyendo), les corresponde media a cada uno y más aún, si está partida en 8 trozos, cada gordito zampará 4 suculentas porciones de una pizza sin piña (si una pizza llevase piña no se consideraría pizza, sino aberración culinaria). ¿Pero qué ocurre si nos dicen: “Hay una pizza y queremos dividir sus 8 deliciosas porciones entre 0 personas”? ¿Cuántas porciones se lleva cada persona? Podéis ver que es una pregunta que no tiene sentido, no hay personas que puedan llevarse pizza así que tampoco es cierto que cada persona se lleve 0 pedazos, nadie se lleva nada, pero todas las personas se llevan algo, como si dijese que toda la gente que mide más de 16 metros puede volar, es cierto porque nadie mide más de 16 metros, pero es mentira porque no hay nadie que mida más de 16 metros para probarlo.


Igual que en el lenguaje, en matemáticas tampoco tiene sentido dividir entre 0 y hay movidas mazo de chungas y tope de raras (en lenguaje técnico lo llamamos así) que harían llorar al niño Jesús si éste hubiera estudiado matemáticas. Los matemáticos normalmente se limitan a evitar el problema acercándose con lo que se llaman “límites”, y resolviendo que cuanto más cercano a 0 es el divisor, más nos acercamos a infinito. Así que la respuesta más bonita a la pregunta sería “algo parecido a infinito”.

¿Cómo resuelve la parte hardware de un ordenador una división? Imaginemos la ya nombrada pizza, humeante, apetitosa, recién cocinada y dispuesta en 8 trozos. Somos de nuevo 2 personas hambrientas y el ordenador lo sabe, así que utiliza el “método de las restas sucesivas”.

Inicio: Restan 8 porciones para acabar la pizza
Ronda 1 – Nos comemos un trozo cada uno, 2 trozos menos (restan 6)
Ronda 2 - Nos comemos 2 trozos (restan 4)
Ronda 3 - Nos comemos 2 trozos (restan 2)
Ronda 4 - Nos comemos 2 trozos (restan 0)
Fin: No quedan trozos de pizza, terminamos

Ese 0 es el resto de nuestra división, ¿Y el resultado? Cuatro, las 4 rondas en las que nos hemos comido nuestra pizza. Por lo tanto, lo que un microchip hace para dividir, es restar hasta que quedan menos porciones que gente para comer y los trozos que quedan sin comer, son el resto.

Imaginemos que esa pizza se la comen 3 personas:
Inicio: 8 porciones
Ronda 1 - Se comen 3 trozos, resto 5
Ronda 2 - Se comen 3 trozos, resto 2
Fin: Quedan 2 trozos, son 3 personas, terminamos.

Aquí podéis ver que el resultado es 2, y sobran 2 trozos por los que tendrán que luchar a muerte o partirlos de forma inexacta con un cuchillo (no voy a hablar de decimales).

¿Qué pasa si el divisor es 0?
Tenemos 8 trozos de pizza
Inicio: 8 porciones

Ronda 1 - Las 0 personas se comen 0 trozos, quedan 8
Ronda 2 - Se comen 0 trozos, quedan 8
Ronda 10.000 - Se comen 0 trozos, quedan 8 porciones, la pizza sigue entera

Como podéis ver, al restarse de 0 en 0, el cálculo nunca pararía, y seguiría así hasta el fin de los tiempos, en un bucle infinito de hardware. Por este motivo, dividir por cero en programación es un error, y si lo haces, el hardware mandará a paseo tu programa, porque la calculadora del ordenador ya está avisada: “Si recibes un 0, dile que aquí no nos andamos con tonterías”. De esta forma cuando se ejecute dependiendo del lenguaje de programación puede ser que el  ordenador estalle programa devuelva un error o que el valor recibido sea del estilo NaN (Not a Number).

Así que ya sabéis, no dejéis a vuestros niños dividir entre 0. ¿Tenéis problemas con las divisiones?