logo

Eroare în virgulă mobilă în Python

Python, un limbaj de programare utilizat pe scară largă, excelează în sarcinile de calcul numeric, dar nu este imun la provocările generate de aritmetica în virgulă mobilă. Numerele în virgulă mobilă în Python sunt aproximări ale numerelor reale, conducând la erori de rotunjire, pierderi de precizie și anulări care poate arunca calculele. Putem identificați aceste erori căutând rezultate ciudate și folosind instrumentenumpy.finfo>la monitorizarea preciziei . Cu ceva prudență și trucuri inteligente, putem ține sub control aceste erori și asigurați-vă că calculele noastre Python sunt fiabile. În acest articol, vom explora complexitățile erorilor în virgulă mobilă Piton .

Ce sunt numerele cu virgulă mobilă?

Numerele în virgulă mobilă sunt o modalitate eficientă de a reprezenta numere reale în computere. Ele constau din trei părți:



  • Semnificativ: Cifrele reale care reprezintă numărul (de exemplu, 3.14159)
  • Exponent: Spune câte locuri pentru a muta semnificația la stânga sau la dreapta (de exemplu, -2 în 3,14159 x 10^-2)
  • Baza: De obicei, 2 pentru computere, determinând modul în care numerele sunt reprezentate intern

De ce apar erori în virgulă mobilă?

Erorile în virgulă mobilă apar deoarece computerele stochează numere reale folosind un număr finit de biți, ceea ce duce la aproximări și potențiale inexactități. Numerele în virgulă mobilă au limitări intrinseci:

  • Precizie finită: Doar un număr limitat de cifre poate fi stocat în semnificație, conducând la erori de rotunjire când reprezintă zecimale exacte.
  • Pierderea preciziei: Operațiuni precum adunarea sau scăderea pot reduce și mai mult precizia, agravând efectele rotunjirii.
  • Depășire/depășire: Numerele extrem de mici sau mari pot fi în afara intervalului reprezentabil, ceea ce duce la underflow (devine zero) sau revărsare (devine infinit).

Tipuri de erori în virgulă mobilă

a) Erori de rotunjire: Cel mai frecvent, care apare atunci când o zecimală exactă trebuie aproximată pentru a se potrivi cu precizia limitată a unui float.

b) Pierderea preciziei: Operațiunile ulterioare pot acumula treptat erori de rotunjire, ducând la inexactități semnificative în rezultatul final.



c) Anulare catastrofală: Când se scad numere aproape egale cu semne opuse, cifrele lor semnificative se anulează, lăsând un rezultat mic și inexact.

operator java

d) Overflow/Underflow: Acestea apar atunci când calculele depășesc intervalul reprezentabil de valori flotante, ceea ce duce la rezultate inexacte sau lipsite de sens.

Detectarea erorilor în virgulă mobilă

  1. Observarea rezultatelor neașteptate: Compararea valorilor calculate cu rezultatele așteptate sau vizualizarea datelor poate dezvălui inconsecvențe cauzate adesea de erori.
  2. Folosind biblioteci precum numpy.finfo> : Biblioteci canumpy>oferi instrumente precumfinfo>pentru a verifica precizia și limitările diferitelor tipuri de date float.

Eroare Python în virgulă mobilă

Aici vom discuta diferite tipuri de exemple care ilustrează erori în virgulă mobilă în Python:



Pierderea preciziei în conversia zecimală în binară

În acest exemplu, numărul zecimal 0,1 este convertit în binar. Datorită expansiunii binare infinite de 0,1, se utilizează doar un număr finit de biți, ceea ce duce la o pierdere a preciziei.

Python3




decimal_number>=> 0.1> binary_representation>=> format>(decimal_number,>'.30f'>)># 30 decimal places> print>(f>'Decimal: {decimal_number} Binary: {binary_representation}'>)>

>

>

Ieșire:

Decimal: 0.1 Binary: 0.100000000000000005551115123126>

Erori de rotunjire

Aici, rezultatul adunării a 1/3 de trei ori este de așteptat să fie 1,0. Cu toate acestea, din cauza erorilor de rotunjire în reprezentarea a 1/3, suma poate să nu fie exact 1,0.

Python3




result>=> 1.0> /> 3.0> sum_result>=> result>+> result>+> result> print>(f>'Expected Result: 1.0 Actual Result: {sum_result}'>)>

>

>

Ieșire:

Expected Result: 1.0 Actual Result: 1.0>

Erori acumulate în calculele iterative

Acest exemplu demonstrează modul în care erorile acumulative pot apărea în calculele iterative. Adăugarea a 0,1 de zece ori poate să nu producă un rezultat exact de 1,0 din cauza limitărilor de precizie în virgulă mobilă.

Python3




total>=> 0.0> for> i>in> range>(>10>):> >total>+>=> 0.1> print>(f>'Expected Result: 1.0 Actual Result: {total}'>)>

>

>

Ieșire:

Expected Result: 1.0 Actual Result: 0.9999999999999999>

Probleme de comparație

În acest caz, compararea sumei 0,1 și 0,2 cu 0,3 poate să nu dea rezultatul așteptat.True>rezultat din cauza impreciziei inerente numerelor în virgulă mobilă.

Python3




a>=> 0.1> +> 0.2> b>=> 0.3> print>(f>'a: {a} b: {b} Equal: {a == b}'>)>

>

>

Ieșire:

a: 0.30000000000000004 b: 0.3 Equal: False>

Rezultate neașteptate în calcule

Aici, scăderea lui1e16>din suma(1e16 + 1)>se așteaptă să producă 1, dar din cauza erorilor în virgulă mobilă, rezultatul poate să nu fie exact 1.

Python3




a>=> 0.1> +> 0.2> b>=> 0.3> print>(f>'a: {a} b: {b} Equal: {a == b}'>)>

>

marca html

>

Ieșire:

Expected Result: 1 Actual Result: 0.0>

Înțelegerea preciziei în virgulă mobilă

Aici vom înțelege precizia în virgulă mobilă: Anomalia 1.2 – 1.0 în Python-

Provocări de reprezentare

După cum se știe că 1,2 – 1,0 = 0,2. Dar când încerci să faci același lucru în Python, vei fi surprins de rezultate:

>>> 1,2 - 1,0>

Ieșire:

0.199999999999999996>

Acest lucru poate fi considerat o eroare în Python, dar nu este. Acest lucru are puțin de-a face cu Python și mult mai mult cu modul în care platforma de bază gestionează numerele în virgulă mobilă. Este un caz normal întâlnit la manipularea numerelor în virgulă mobilă în interiorul unui sistem. Este o problemă cauzată de reprezentarea internă a numerelor în virgulă mobilă, care utilizează un număr fix de cifre binare pentru a reprezenta un număr zecimal. Este dificil să se reprezinte unele numere zecimale în binar, așa că, în multe cazuri, duce la mici erori de rotunjire. Cunoaștem cazuri similare în matematica zecimală, multe rezultate nu pot fi reprezentate cu un număr fix de cifre zecimale, pentru Exemplu

10 / 3 = 3.33333333.......>

În acest caz, luând ca exemplu 1,2, reprezentarea lui 0,2 în binar este 0,00110011001100110011001100…… și așa mai departe. Este dificil să stocați în interior acest număr zecimal infinit. În mod normal, valoarea unui obiect flotant este stocată în virgulă mobilă binar cu o precizie fixă ​​( de obicei 53 de biți ). Așa că reprezentăm 1.2 intern ca,

1.0011001100110011001100110011001100110011001100110011>

Care este exact egal cu:

1.1999999999999999555910790149937383830547332763671875>

Gestionarea erorii în virgulă mobilă

Aici vom discuta diferite exemple despre cum să gestionăm erorile în virgulă mobilă în Python:

Rotunjirea la o anumită zecimală

Rotunjind rezultatul la o anumită zecimală (de exemplu, 2), puteți atenua impactul erorilor mici în virgulă mobilă.

Python3




result>=> 1.2> -> 1.0> rounded_result>=> round>(result,>2>)> print>(f>'Original Result: {result} Rounded Result: {rounded_result}'>)>

>

>

Ieșire:

Original Result: 0.19999999999999996 Rounded Result: 0.2>

Utilizarea clasei zecimale pentru precizie ridicată

Thedecimal>modulul oferăDecimal>clasă, permițând o precizie mai mare aritmetică. Setarea preciziei cugetcontext().prec>poate ajuta la gestionarea preciziei pentru calcule specifice

Python3




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}'>)>

>

>

Ieșire:

High Precision Result: 0.2>

Utilizarea fracțiilor pentru reprezentări exacte

Thefractions>modulul permite lucrul cu reprezentări fracționale exacte, evitând erorile în virgulă mobilă.

Python3




from> fractions>import> Fraction> result>=> Fraction(>'1.2'>)>-> Fraction(>'1.0'>)> print>(f>'Exact Fractional Result: {result}'>)>

>

>

Ieșire:

Exact Fractional Result: 1/5>

Gestionarea rezultatelor intermediare cu zecimală

FoloseșteDecimal>clasă pentru calcule intermediare pentru a minimiza erorile cumulate înainte de convertirea înapoi în float.

Python3




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}'>)>

>

cum să obțineți data curentă în java

>

Ieșire:

Intermediate Result: 0.2 Final Result: 0.2>

Concluzie

Totuși, te gândești de ce python nu rezolvă această problemă , de fapt nu are nimic de-a face cu python. Se întâmplă pentru că acesta este modul în care platforma c subiacentă gestionează numerele în virgulă mobilă și, în cele din urmă, cu inexactitatea, vom fi scris întotdeauna numerele ca un șir de cifre fix. Rețineți că acest lucru este în însăși natura virgulei mobile binare: nici acesta nu este o eroare în Piton sau C , și nici nu este o eroare în codul dvs. Veți vedea același tip de comportamente în toate limbile care acceptă aritmetica în virgulă mobilă a hardware-ului nostru, deși este posibil ca unele limbi să nu afișeze diferența în mod implicit sau în toate modurile de ieșire). Trebuie să luăm în considerare acest comportament atunci când ne pasă de problemele de matematică cu precizie exactă sau folosirea lui în declarații condiționale. Verifica punctul de plutire secțiunea din documentația python pentru mai multe astfel de comportamente.

Întrebări frecvente (Întrebări frecvente)

1. Ce este o eroare în virgulă mobilă în Python?

O eroare în virgulă mobilă în Python se referă la discrepanțe între rezultatele așteptate și cele reale atunci când se lucrează cu numere în virgulă mobilă, care decurg din limitările reprezentării numerelor reale într-un sistem bazat pe binar.

2. De ce 1.2 - 1.0> nu este egal 0.2> în Python?

Discrepanța se datorează provocărilor inerente în reprezentarea numerelor zecimale în binar. Erorile de rotunjire apar în timpul reprezentării binare interne, ducând la rezultate neașteptate.

3. Este eroarea în virgulă mobilă o eroare în Python?

Nu, nu este o eroare în Python. Este o problemă comună în calcul legată de modul în care numerele în virgulă mobilă sunt reprezentate intern. Python aderă la standardul IEEE 754 pentru aritmetica în virgulă mobilă.

4. Cum pot rotunji un rezultat în virgulă mobilă la o anumită zecimală?

Puteți folosiround()>funcția de rotunjire a unui rezultat în virgulă mobilă la o anumită zecimală. De exemplu,rounded_result = round(result, 2)>.

5. Ce este decimal> modul și cum ajută la gestionarea erorilor în virgulă mobilă?

Thedecimal>modulul oferăDecimal>clasa pentru aritmetica de precizie mai mare. Setarea preciziei și utilizareaDecimal>poate ajuta la atenuarea erorilor în virgulă mobilă.