Professional Documents
Culture Documents
0.125
...tieneelvalor1/10+2/100+5/1000,ydelamismamaneralafraccinbinaria
0.001
...tieneelvalor0/2+0/4+1/8.Estasdosfraccionestienenvaloresidnticos,lanicadiferencia
realesquelaprimeraestescritaennotacinfraccionalenbase10ylasegundaenbase2.
El problema es ms fcil de entender primero en base 10. Consider la fraccin 1/3. Pods
aproximarlacomounafraccindebase10
0.3
...o,mejor,
0.33
...o,mejor,
0.333
...yas.Noimportacuantosdgitosdeseesescribir,elresultadonuncaserexactamente1/3,pero
serunaaproximacincadavezmejorde1/3.
Delamismamanera,noimportacuantosdgitosenbase2quierasusar,elvalordecimal0.1no
puederepresentarseexactamentecomounafraccinenbase2.Enbase2,1/10eslasiguiente
fraccinqueserepiteinfinitamente:
0.0001100110011001100110011001100110011001100110011...
Frenencualquiernmerofinitodebits,ytendrsunaaproximacin.Esporestoquevescosas
como:
>>>0.1
0.10000000000000001
http://docs.python.org.ar/tutorial/2/floatingpoint.html 1/5
5/1/2017 14.AritmticadePuntoFlotante:ProblemasyLimitacionesTutorialdePythonv2.7.0
Enlamayoradelasmquinasdehoyenda,esoesloqueverssiingress0.1enunpromptde
Python. Quizs no, sin embargo, porque la cantidad de bits usados por el hardware para
almacenar valores de punto flotante puede variar en las distintas mquinas, y Python slo
muestraunaaproximacindelvalordecimalverdaderodelaaproximacinbinariaguardadaporla
mquina.Enlamayoradelasmquinas,siPythonfueraamostrarelverdaderovalordecimalde
laaproximacinalmacenadapor0.1,tendraquemostrarsinembargo
>>>0.1
0.1000000000000000055511151231257827021181583404541015625
El prompt de Python usa la funcin integrada repr() para obtener una versin en cadena de
caracteres de todo lo que muestra. Para flotantes, repr(float) redondea el valor decimal
verdaderoa17dgitossignificativos,dando
0.10000000000000001
repr(float)
produce 17 dgitos significativos porque esto es suficiente (en la mayora de las
mquinas)paraquesecumpla eval(repr(x))==x exactamenteparatodoslosflotantesfinitosX,
peroredondeandoa16dgitosnoessuficienteparaqueseaverdadero.
Notqueestaeslaverdaderanaturalezadelpuntoflotantebinario:noesunerrordePython,y
tampoco es un error en tu cdigo. Vers lo mismo en todos los lenguajes que soportan la
aritmticadepuntoflotantedetuhardware(apesardequeenalgunoslenguajesporomisinno
muestrenladiferencia,onolohaganentodoslosmodosdesalida).
>>>printstr(0.1)
0.1
Esimportantedarsecuentadequeestoes,realmente,unailusin:elvalorenlamquinanoes
exactamente1/10,simplementeestsredondeandoelvalorquesemuestra del valor verdadero
delamquina.
Aestasesiguenotrassorpresas.Porejemplo,luegodever:
>>>0.1
0.10000000000000001
...quizs ests tentado de usar la funcin round() para recortar el resultado al dgito que
esperabas.Peroeslomismo:
>>>round(0.1,1)
0.10000000000000001
El problema es que el valor de punto flotante binario almacenado para 0.1 ya era la mejor
aproximacinbinariaposiblede1/10,demaneraqueintentarredondearlanuevamentenopuede
mejorarla:yaeralamejorposible.
http://docs.python.org.ar/tutorial/2/floatingpoint.html 2/5
5/1/2017 14.AritmticadePuntoFlotante:ProblemasyLimitacionesTutorialdePythonv2.7.0
>>>suma=0.0
>>>foriinrange(10):
...suma+=0.1
...
>>>suma
0.9999999999999999
Laaritmticadepuntoflotantebinariatienevariassorpresascomoesta.Elproblemacon0.1es
explicadocondetalleabajo,enlaseccinErrordeRepresentacin.MirlosPeligrosdelPunto
Flotante (en ingls, The Perils of Floating Point) para una ms completa recopilacin de otras
sorpresasnormales.
Comodicecercadelfinal,nohayrespuestasfciles.Apesardeeso,noletengasmuchomiedo
alpuntoflotante!LoserroresenlasoperacionesflotantesdePythonseheredandelhardwarede
puntoflotante,yenlamayoradelasmquinasestnenelordendenomsdeuna1parteen
2**53 por operacin. Eso es ms que adecuado para la mayora de las tareas, pero necesits
tener en cuenta que no es aritmtica decimal, y que cada operacin de punto flotante sufre un
nuevoerrorderedondeo.
Apesardequeexistencasospatolgicos,paralamayoradeusoscasualesdelaaritmticade
puntoflotantealfinalverselresultadoqueesperssisimplementeredondesloquemostrsde
tus resultados finales al nmero de dgitos decimales que espers. str() es normalmente
suficiente,yparauncontrolmsfinomirlosparmetrosdelmtododeformateo str.format() en
formatstrings.
Error de representacin se refiere al hecho de que algunas (la mayora) de las fracciones
decimalesnopuedenrepresentarseexactamentecomofraccionesbinarias(enbase2).Estaesla
raznprincipaldeporquPython(oPerl,C,C++,Java,Fortran,ytantosotros)frecuentemente
nomostrarnelnmerodecimalexactoqueespers:
>>>0.1
0.10000000000000001
1/10~=J/(2**N)
http://docs.python.org.ar/tutorial/2/floatingpoint.html 3/5
5/1/2017 14.AritmticadePuntoFlotante:ProblemasyLimitacionesTutorialdePythonv2.7.0
...como
J~=2**N/10
>>>2**52
4503599627370496L
>>>2**53
9007199254740992L
>>>2**56/10
7205759403792793L
Osea,56eselnicovalorparaNquedejaJconexactamente53bits.Elmejorvalorposiblepara
Jesentonceselcocienteredondeado:
>>>q,r=divmod(2**56,10)
>>>r
6L
Yaqueelrestoesmsquelamitadde10,lamejoraproximacinseobtieneredondendolo:
>>>q+1
7205759403792794L
Porlotantolamejoraproximacina1/10endobleprecisin754esesosobre2**56,o
7205759403792794/72057594037927936
Not que como lo redondeamos, esto es un poquito ms grande que 1/10 si no lo hubiramos
redondeado,elcocientehubiesesidounpoquitomenorque1/10.Peronohaycasoenquesea
exactamente1/10!
>>>.1*2**56
7205759403792794.0
Simultiplicamosesafraccinpor10**30,podemosverelvalor(truncado)desus30dgitosms
significativos:
>>>7205759403792794*10**30/2**56
100000000000000005551115123125L
...loquesignificaqueelvalorexactoalmacenadoenlacomputadoraesaproximadamenteigualal
valordecimal0.100000000000000005551115123125.Redondeandoesoa17dgitossignificativos
dael0.10000000000000001quePythonmuestra(bueno,mostraraencualquierplataformaque
cumplacon754cuyabibliotecaenChagalamejorconversinposibleenentradaysalida...la
tuyaquizsno!).
http://docs.python.org.ar/tutorial/2/floatingpoint.html 4/5
5/1/2017 14.AritmticadePuntoFlotante:ProblemasyLimitacionesTutorialdePythonv2.7.0
http://docs.python.org.ar/tutorial/2/floatingpoint.html 5/5