Python, un llenguatge de programació àmpliament utilitzat, sobresurt en tasques d'informàtica numèrica, però no és immune als reptes que planteja l'aritmètica de coma flotant. Els nombres de coma flotant en Python són aproximacions de nombres reals, que donen lloc a errors d'arrodoniment, pèrdua de precisió i cancel·lacions que pot fer perdre càlculs. Podem detectar aquests errors buscant resultats estranys i utilitzant einesnumpy.finfo>a monitor de precisió . Amb una mica de precaució i trucs intel·ligents, podem mantenir aquests errors sota control i assegurar-nos que els nostres càlculs de Python són fiables. En aquest article, explorarem les complexitats dels errors de coma flotant Python .
Què són els nombres de coma flotant?
Els nombres de coma flotant són una manera eficient de representar nombres reals en ordinadors. Consten de tres parts:
- Significatiu: Els dígits reals que representen el nombre (p. ex., 3,14159)
- Exponent: Indica quants llocs cal moure el significat cap a l'esquerra o cap a la dreta (p. ex., -2 en 3,14159 x 10^-2)
- Base: Normalment 2 per a ordinadors, determinant com es representen els nombres internament
Per què es produeixen errors de coma flotant?
Els errors de coma flotant sorgeixen perquè els ordinadors emmagatzemen nombres reals utilitzant un nombre finit de bits, donant lloc a aproximacions i possibles imprecisions. Els nombres de coma flotant tenen limitacions intrínseques:
- Precisió finita: Només es pot emmagatzemar un nombre limitat de dígits al significat, que condueix a errors d'arrodoniment quan es representen decimals exactes.
- Pèrdua de precisió: Operacions com la suma o la resta poden reduir encara més la precisió, augmentant els efectes de l'arrodoniment.
- Desbordament/desbordament: Nombres extremadament petits o grans poden quedar fora del rang representable, donant lloc a desbordament inferior (esdevé zero) o desbordament (es converteix en infinit).
Tipus d'errors de coma flotant
a) Errors d'arrodoniment: El més comú, es produeix quan s'ha d'aproximar un decimal exacte per adaptar-se a la precisió limitada d'un flotador.
b) Pèrdua de precisió: Les operacions posteriors poden acumular errors d'arrodoniment gradualment, donant lloc a importants imprecisions en el resultat final.
c) Cancel·lació catastròfica: En restar nombres gairebé iguals amb signes oposats, els seus dígits significatius es cancel·len, deixant un resultat petit i imprecís.
d) Desbordament/subeiximent: Es produeixen quan els càlculs superen l'interval representable de valors flotants, donant lloc a resultats inexactes o sense sentit.
Detecció d'errors de coma flotant
- Observant resultats inesperats: La comparació dels valors calculats amb els resultats esperats o la visualització de dades poden revelar inconsistències causades sovint per errors.
- Utilitzant biblioteques com
numpy.finfo>: Biblioteques comnumpy>proporcionar eines comfinfo>per comprovar la precisió i les limitacions dels diferents tipus de dades flotants.
Error de punt flotant de Python
Aquí parlarem de diferents tipus d'exemples que il·lustren errors de coma flotant a Python:
Pèrdua de precisió en la conversió decimal a binària
En aquest exemple, el nombre decimal 0,1 es converteix en binari. A causa de l'expansió binària infinita de 0,1, només s'utilitza un nombre finit de bits, la qual cosa comporta una pèrdua de precisió.
Python 3
decimal_number>=> 0.1> binary_representation>=> format>(decimal_number,>'.30f'>)># 30 decimal places> print>(f>'Decimal: {decimal_number}
Binary: {binary_representation}'>)> |
>
>
Sortida:
Decimal: 0.1 Binary: 0.100000000000000005551115123126>
Errors d'arrodoniment
Aquí, s'espera que el resultat de la suma d'1/3 de tres vegades sigui 1,0. Tanmateix, a causa dels errors d'arrodoniment en representar 1/3, la suma pot no ser exactament 1,0.
Python 3
result>=> 1.0> /> 3.0> sum_result>=> result>+> result>+> result> print>(f>'Expected Result: 1.0
Actual Result: {sum_result}'>)> |
>
>
Sortida:
char a nombre enter java
Expected Result: 1.0 Actual Result: 1.0>
Errors acumulatius en càlculs iteratius
Aquest exemple demostra com es poden produir errors acumulatius en càlculs iteratius. L'addició de 0,1 deu vegades pot no produir un resultat exacte d'1,0 a causa de les limitacions de precisió de coma flotant.
Python 3
total>=> 0.0> for> i>in> range>(>10>):> >total>+>=> 0.1> print>(f>'Expected Result: 1.0
Actual Result: {total}'>)> |
>
>
Sortida:
Expected Result: 1.0 Actual Result: 0.9999999999999999>
Problemes de comparació
En aquest cas, comparar la suma de 0,1 i 0,2 amb 0,3 pot no produir l'esperatTrue>resultat a causa de la imprecisió inherent dels nombres de coma flotant.
Python 3
a>=> 0.1> +> 0.2> b>=> 0.3> print>(f>'a: {a}
b: {b}
Equal: {a == b}'>)> |
>
>
Sortida:
a: 0.30000000000000004 b: 0.3 Equal: False>
Resultats inesperats en càlculs
Aquí, la resta de1e16>de la suma(1e16 + 1)>s'espera que doni 1, però a causa dels errors de coma flotant, és possible que el resultat no sigui exactament 1.
Python 3
a>=> 0.1> +> 0.2> b>=> 0.3> print>(f>'a: {a}
b: {b}
Equal: {a == b}'>)> |
>
>
Sortida:
Expected Result: 1 Actual Result: 0.0>
Comprensió de la precisió de coma flotant
Aquí entendrem la precisió del punt flotant: L'anomalia 1.2 - 1.0 a Python-
Reptes de representació
Com se sap que 1,2 – 1,0 = 0,2. Però quan intenteu fer el mateix a Python, us sorprendrà els resultats:
>>> 1.2 - 1.0>
Sortida:
0.199999999999999996>
Això es pot considerar un error a Python, però no ho és. Això té poc a veure amb Python i molt més a veure amb la manera com la plataforma subjacent gestiona els nombres de coma flotant. És un cas normal que es troba quan es manegen internament nombres de coma flotant en un sistema. És un problema causat quan la representació interna de nombres de coma flotant, que utilitza un nombre fix de dígits binaris per representar un nombre decimal. És difícil representar alguns nombres decimals en binari, de manera que, en molts casos, comporta petits errors d'arrodoniment. Coneixem casos similars en matemàtiques decimals, molts resultats no es poden representar amb un nombre fix de dígits decimals, per Exemple
10 / 3 = 3.33333333.......>
En aquest cas, prenent 1,2 com a exemple, la representació de 0,2 en binari és 0,00110011001100110011001100…… i així successivament. És difícil emmagatzemar internament aquest nombre decimal infinit. Normalment, el valor d'un objecte flotant s'emmagatzema en coma flotant binari amb una precisió fixa ( normalment 53 bits ). Així que representem 1.2 internament com,
1.0011001100110011001100110011001100110011001100110011>
Que és exactament igual a:
1.1999999999999999555910790149937383830547332763671875>
Gestió d'errors de coma flotant
Aquí parlarem de diferents exemples sobre com gestionar els errors de punt flotant a Python:
Arrodonit a una posició decimal específica
En arrodonir el resultat a una posició decimal específica (p. ex., 2), podeu mitigar l'impacte dels petits errors de coma flotant.
Python 3
result>=> 1.2> -> 1.0> rounded_result>=> round>(result,>2>)> print>(f>'Original Result: {result}
Rounded Result: {rounded_result}'>)> |
>
>
Sortida:
Original Result: 0.19999999999999996 Rounded Result: 0.2>
Ús de la classe decimal per a alta precisió
Eldecimal>mòdul proporciona elDecimal>classe, permetent una aritmètica més precisa. Configurant la precisió ambgetcontext().prec>pot ajudar a gestionar la precisió per a càlculs específics
Python 3
from> decimal>import> Decimal, getcontext> getcontext().prec>=> 4> # Set precision to 4 decimal places> result>=> Decimal(>'1.2'>)>-> Decimal(>'1.0'>)> print>(f>'High Precision Result: {result}'>)> |
>
>
Sortida:
High Precision Result: 0.2>
Ús de fraccions per a representacions exactes
Elfractions>El mòdul permet treballar amb representacions fraccionals exactes, evitant errors de coma flotant.
Python 3
from> fractions>import> Fraction> result>=> Fraction(>'1.2'>)>-> Fraction(>'1.0'>)> print>(f>'Exact Fractional Result: {result}'>)> |
>
>
Sortida:
Exact Fractional Result: 1/5>
Maneig de resultats intermedis amb decimals
Utilitzar elDecimal>classe per a càlculs intermedis per minimitzar els errors acumulats abans de tornar a convertir a flotant.
Python 3
from> decimal>import> Decimal, getcontext> getcontext().prec>=> 6> # Set precision to 6 decimal places> intermediate_result>=> Decimal(>'1.2'>)>-> Decimal(>'1.0'>)> final_result>=> float>(intermediate_result)># Convert back to float if needed> print>(f>'Intermediate Result: {intermediate_result}
Final Result: {final_result}'>)> |
>
>
Sortida:
Intermediate Result: 0.2 Final Result: 0.2>
Conclusió
Tot i així, estàs pensant per què Python no resol aquest problema , en realitat no té res a veure amb Python. Passa perquè és la forma en què la plataforma c subjacent gestiona els nombres de coma flotant i, en última instància, amb la imprecisió, sempre haurem estat escrivint números com una cadena de nombre fix de dígits. Tingueu en compte que això és de la naturalesa del punt flotant binari: tampoc no és un error Python o C , i tampoc és un error al vostre codi. Veureu el mateix tipus de comportaments en tots els idiomes que admeten l'aritmètica de coma flotant del nostre maquinari, tot i que alguns idiomes poden no mostrar la diferència per defecte o en tots els modes de sortida). Hem de tenir en compte aquest comportament quan ens preocupem pels problemes matemàtics amb precisions exactes o quan l'utilitzem dins d'enunciats condicionals. Comproveu punt flotant secció a la documentació de Python per a més comportaments d'aquest tipus.
matriu en cadena
Preguntes freqüents (FAQ)
1. Què és un error de coma flotant a Python?
Un error de coma flotant a Python es refereix a discrepàncies entre els resultats esperats i reals quan es treballa amb nombres de coma flotant, que sorgeixen de les limitacions de representar nombres reals en un sistema binari.
2. Per què ho fa 1.2 - 1.0> no igual 0.2> en Python?
La discrepància es deu als reptes inherents a la representació de nombres decimals en binari. Els errors d'arrodoniment es produeixen durant la representació binària interna, donant lloc a resultats inesperats.
3. L'error de coma flotant és un error a Python?
No, no és un error a Python. És un problema comú en la informàtica relacionat amb com es representen internament els nombres de coma flotant. Python s'adhereix a l'estàndard IEEE 754 per a l'aritmètica de coma flotant.
4. Com puc arrodonir un resultat de coma flotant a una posició decimal específica?
Podeu utilitzar el
round()>funció per arrodonir un resultat de coma flotant a una posició decimal específica. Per exemple,rounded_result = round(result, 2)>.
5. Que es el decimal> mòdul, i com ajuda a gestionar els errors de coma flotant?
El
decimal>mòdul proporciona elDecimal>classe per a l'aritmètica de més precisió. Configuració de la precisió i úsDecimal>pot ajudar a mitigar els errors de coma flotant.