Así que ha escrito un código absurdamente simple, digamos, por ejemplo:
>>> 0.1 + 0.2
y obtuve un resultado realmente inesperado:
>>> 0.1 + 0.2
0.30000000000000004
>>>
Esto se debe a que, internamente, las computadoras usan un formato (punto flotante binario) que no puede representar con precisión un número como 0.1, 0.2 o 0.3 en absoluto.
La matemática de coma flotante binaria es así. En la mayoría de los lenguajes de programación, se basa en el estándar IEEE 754. El meollo del problema es que los números se representan en este formato como un número entero multiplicado por una potencia de dos.
¿Por qué pasó esto?
De hecho, es bastante interesante. Cuando tienes un sistema de base 10 (como el nuestro), solo puede expresar fracciones que usan un factor primo de la base. Los factores primos de 10 son 2 y 5. Entonces 1/2, 1/4, 1/5, 1/8 y 1/10 pueden expresarse claramente porque todos los denominadores usan factores primos de 10. En contraste, 1/3, 1/6, 1/7 y 1/9 son decimales periódicos porque sus denominadores usan un factor primo de 3 o 7.
En binario (o base 2), el único factor primo es 2, por lo que solo puede expresar claramente fracciones cuyo denominador tenga solo 2 como factor primo. En binario, 1/2, 1/4, 1/8 se expresarían claramente como decimales, mientras que 1/5 o 1/10 serían decimales repetidos. Entonces 0.1 y 0.2 (1/10 y 1/5), mientras que los decimales limpios en un sistema de base 10, son decimales repetidos en el sistema de base 2 que usa la computadora. Cuando realiza cálculos matemáticos con estos decimales repetidos, termina con sobras que se transfieren cuando convierte el número de base 2 (binario) de la computadora en una representación de base 10 más legible por humanos.
¿Por qué las computadoras usan un sistema tan raro?
No es raro, solo diferente. Los números decimales no pueden representar con precisión un número como 1/3, por lo que tienes que redondear a algo como 0,33, y tampoco esperas que 0,33 + 0,33 + 0,33 sumen 1, ¿verdad?
Las computadoras usan números binarios porque son más rápidos para manejarlos, y porque para la mayoría de los cálculos, un pequeño error en el decimoséptimo lugar decimal no importa en absoluto, ya que los números con los que trabaja no son redondos (ni tan precisos) de todos modos.
¿Por qué otros cálculos como 0,1 + 0,4 funcionan correctamente?
En ese caso, el resultado (0.5) se puede representar exactamente como un número de punto flotante, y es posible que los errores de redondeo en los números de entrada se cancelen entre sí, pero no necesariamente se puede confiar en eso (por ejemplo, cuando esos dos los números se almacenaron primero en representaciones de punto flotante de diferentes tamaños, es posible que los errores de redondeo no se compensen entre sí).
¿Cómo lo resuelvo?
Para Python podemos usar:
x = .1 + .2
#x = 0.30000000000000004
y = float(decimal.Decimal(‘.1’) + decimal.Decimal(‘.2’))
#y = 0.3
Para Javascript se puede utilizar la librería http://mikemcl.github.io/decimal.js/
I discovered your blog web site on google and test just a few of your early posts. Proceed to maintain up the very good operate. I just additional up your RSS feed to my MSN News Reader. Searching for ahead to studying more from you afterward!…
Your blog is a constant source of inspiration for me. Your passion for your subject matter shines through in every post, and it’s clear that you genuinely care about making a positive impact on your readers.
Hello my family member! I want to say that this article is amazing, nice written and come with approximately all vital infos. I’d like to see extra posts like this .
The next time I learn a weblog, I hope that it doesnt disappoint me as a lot as this one. I imply, I know it was my choice to read, however I actually thought youd have something attention-grabbing to say. All I hear is a bunch of whining about one thing that you could possibly fix for those who werent too busy looking for attention.
I am continuously looking online for ideas that can benefit me. Thx!
It’s really a nice and useful piece of information. I am glad that you shared this useful info with us. Please keep us up to date like this. Thanks for sharing.