logo

Errore in virgola mobile in Python

Python, un linguaggio di programmazione ampiamente utilizzato, eccelle nei compiti di calcolo numerico, ma non è immune alle sfide poste dall’aritmetica in virgola mobile. I numeri in virgola mobile in Python sono approssimazioni dei numeri reali, che portano a errori di arrotondamento, perdita di precisione e cancellazioni che può confondere i calcoli. Noi possiamo individuare questi errori cercando risultati strani e utilizzando strumentinumpy.finfo>A monitorare la precisione . Con un po’ di cautela e trucchi intelligenti, possiamo tenere sotto controllo questi errori e garantire che i nostri calcoli Python siano affidabili. In questo articolo esploreremo le complessità degli errori in virgola mobile Pitone .

Cosa sono i numeri in virgola mobile?

I numeri in virgola mobile sono un modo efficiente per rappresentare i numeri reali nei computer. Sono costituiti da tre parti:



  • Significativo: Le cifre effettive che rappresentano il numero (ad esempio, 3.14159)
  • Esponente: Indica di quante posizioni spostare il significato a sinistra o a destra (ad esempio, -2 in 3.14159 x 10^-2)
  • Base: Tipicamente 2 per i computer, che determina il modo in cui i numeri vengono rappresentati internamente

Perché si verificano errori in virgola mobile?

Gli errori in virgola mobile si verificano perché i computer memorizzano numeri reali utilizzando un numero finito di bit, portando ad approssimazioni e potenziali imprecisioni. I numeri in virgola mobile hanno limitazioni intrinseche:

  • Precisione finita: Solo un numero limitato di cifre può essere memorizzato nel significato, che porta a errori di arrotondamento quando si rappresentano i decimali esatti.
  • Perdita di precisione: Operazioni come addizione o sottrazione possono ridurre ulteriormente la precisione, aggravando gli effetti dell'arrotondamento.
  • Underflow/overflow: Numeri estremamente piccoli o grandi possono non rientrare nell'intervallo rappresentabile, portando a sottoflusso (diventa zero) o traboccamento (diventa infinito).

Tipi di errori in virgola mobile

a) Errori di arrotondamento: Il più comune, che si verifica quando un decimale esatto deve essere approssimato per adattarsi alla precisione limitata di un float.

b) Perdita di precisione: Le operazioni successive possono accumulare gradualmente errori di arrotondamento, portando a significative imprecisioni nel risultato finale.



c) Cancellazione catastrofica: Quando si sottraggono numeri quasi uguali con segni opposti, le loro cifre significative si cancellano, lasciando un risultato piccolo e impreciso.

d) Overflow/Underflow: Questi si verificano quando i calcoli superano l'intervallo rappresentabile dei valori float, portando a risultati imprecisi o privi di significato.

Rilevamento degli errori in virgola mobile

  1. Osservazione di risultati imprevisti: Il confronto dei valori calcolati con i risultati attesi o la visualizzazione dei dati può rivelare incoerenze spesso causate da errori.
  2. Utilizzando librerie come numpy.finfo> : Alle biblioteche piacenumpy>fornire strumenti comefinfo>per verificare la precisione e le limitazioni dei diversi tipi di dati float.

Errore in virgola mobile Python

Qui discuteremo diversi tipi di esempi che illustrano gli errori in virgola mobile in Python:



Perdita di precisione nella conversione da decimale a binario

In questo esempio, il numero decimale 0,1 viene convertito in binario. A causa dell'espansione binaria infinita di 0,1, viene utilizzato solo un numero finito di bit, con conseguente perdita di precisione.

Python3

algoritmo minimax




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

>

>

Produzione:

Decimal: 0.1 Binary: 0.100000000000000005551115123126>

Errori di arrotondamento

In questo caso, il risultato della somma di 1/3 di tre volte dovrebbe essere 1,0. Tuttavia, a causa di errori di arrotondamento nella rappresentazione di 1/3, la somma potrebbe non essere esattamente 1,0.

Python3




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

>

>

Produzione:

Expected Result: 1.0 Actual Result: 1.0>

Errori cumulativi nei calcoli iterativi

Questo esempio dimostra come possono verificarsi errori cumulativi nei calcoli iterativi. L'aggiunta di 0,1 dieci volte potrebbe non produrre un risultato esatto di 1,0 a causa delle limitazioni della precisione in virgola mobile.

Python3




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

>

>

Produzione:

Expected Result: 1.0 Actual Result: 0.9999999999999999>

Problemi di confronto

In questo caso, il confronto tra la somma di 0,1 e 0,2 e 0,3 potrebbe non dare i risultati attesiTrue>risultato dovuto all’imprecisione intrinseca dei numeri in virgola mobile.

Python3




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

costruttore in Java
>

>

Produzione:

a: 0.30000000000000004 b: 0.3 Equal: False>

Risultati imprevisti nei calcoli

Qui, la sottrazione di1e16>dalla somma(1e16 + 1)>si prevede che restituisca 1, ma a causa di errori in virgola mobile, il risultato potrebbe non essere esattamente 1.

Python3




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

>

>

Produzione:

Expected Result: 1 Actual Result: 0.0>

Comprendere la precisione in virgola mobile

Qui comprenderemo la precisione in virgola mobile: L'anomalia 1.2 – 1.0 in Python-

Sfide di rappresentazione

Come è noto che 1.2 – 1.0 = 0.2. Ma quando provi a fare lo stesso in Python rimarrai sorpreso dai risultati:

>>> 1.2 - 1.0>

Produzione:

0.199999999999999996>

Questo può essere considerato un bug in Python, ma non lo è. Questo ha poco a che fare con Python e molto di più con il modo in cui la piattaforma sottostante gestisce i numeri in virgola mobile. È un caso normale riscontrato quando si gestiscono numeri a virgola mobile internamente in un sistema. È un problema causato dalla rappresentazione interna dei numeri a virgola mobile, che utilizza un numero fisso di cifre binarie per rappresentare un numero decimale. È difficile rappresentare alcuni numeri decimali in formato binario, quindi in molti casi ciò porta a piccoli errori di arrotondamento. Conosciamo casi simili nella matematica decimale, molti risultati non possono essere rappresentati con un numero fisso di cifre decimali, ad esempio Esempio

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

In questo caso, prendendo come esempio 1.2, la rappresentazione di 0.2 in binario è 0.00110011001100110011001100…… e così via. È difficile memorizzare internamente questo numero decimale infinito. Normalmente il valore di un oggetto float viene memorizzato in virgola mobile binaria con una precisione fissa ( tipicamente 53 bit ). Quindi rappresentiamo 1.2 internamente come,

1.0011001100110011001100110011001100110011001100110011>

Che è esattamente uguale a:

1.1999999999999999555910790149937383830547332763671875>

Gestione dell'errore in virgola mobile

Qui discuteremo diversi esempi su come gestire gli errori in virgola mobile in Python:

Arrotondamento a una cifra decimale specifica

Arrotondando il risultato a una cifra decimale specifica (ad esempio 2), è possibile mitigare l'impatto di piccoli errori in virgola mobile.

Python3


chiave di inserimento del laptop



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

>

>

Produzione:

Original Result: 0.19999999999999996 Rounded Result: 0.2>

Utilizzo della classe decimale per l'alta precisione

ILdecimal>il modulo fornisce il fileDecimal>classe, consentendo un'aritmetica di maggiore precisione. Impostazione della precisione congetcontext().prec>può aiutare a gestire la precisione per calcoli specifici

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

>

>

Produzione:

High Precision Result: 0.2>

Utilizzo delle frazioni per rappresentazioni esatte

ILfractions>Il modulo consente di lavorare con rappresentazioni frazionarie esatte, evitando errori in virgola mobile.

Python3




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

>

>

Produzione:

Exact Fractional Result: 1/5>

Gestire i risultati intermedi con i decimali

Usa ilDecimal>classe per i calcoli intermedi per ridurre al minimo gli errori cumulativi prima della riconversione in float.

Python3

cos'è l'oracolo




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

>

>

Produzione:

Intermediate Result: 0.2 Final Result: 0.2>

Conclusione

Eppure stai pensando al perché Python non risolve questo problema , in realtà non ha nulla a che fare con Python. Succede perché è il modo in cui la piattaforma c sottostante gestisce i numeri a virgola mobile e, in definitiva, a causa dell'imprecisione, avremo sempre scritto i numeri come una stringa di un numero fisso di cifre. Si noti che questo è nella natura stessa del binario a virgola mobile: neanche questo è un bug Pitone O C , e non è nemmeno un bug nel tuo codice. Vedrai lo stesso tipo di comportamenti in tutte le lingue che supportano l'aritmetica in virgola mobile del nostro hardware (anche se alcune lingue potrebbero non visualizzare la differenza per impostazione predefinita o in tutte le modalità di output). Dobbiamo considerare questo comportamento quando ci preoccupiamo di problemi di matematica che necessitano di precise precisazioni o se lo utilizziamo all'interno di istruzioni condizionali. Controllo virgola mobile sezione nella documentazione di Python per ulteriori comportamenti simili.

Domande frequenti (FAQ)

1. Cos'è un errore in virgola mobile in Python?

Un errore in virgola mobile in Python si riferisce alle discrepanze tra i risultati attesi e quelli effettivi quando si lavora con numeri in virgola mobile, derivanti dalle limitazioni della rappresentazione dei numeri reali in un sistema basato su binario.

2. Perché lo fa 1.2 - 1.0> non uguale 0.2> in Python?

La discrepanza è dovuta alle sfide intrinseche nella rappresentazione dei numeri decimali in binario. Durante la rappresentazione binaria interna si verificano errori di arrotondamento che portano a risultati imprevisti.

3. L'errore in virgola mobile è un bug in Python?

No, non è un bug in Python. È un problema comune nell’informatica legato al modo in cui i numeri in virgola mobile vengono rappresentati internamente. Python aderisce allo standard IEEE 754 per l'aritmetica in virgola mobile.

4. Come posso arrotondare un risultato in virgola mobile a una cifra decimale specifica?

Puoi usare ilround()>funzione per arrotondare un risultato in virgola mobile a una specifica cifra decimale. Per esempio,rounded_result = round(result, 2)>.

5. Quale è decimal> modulo e come aiuta a gestire gli errori in virgola mobile?

ILdecimal>il modulo fornisce il fileDecimal>classe per aritmetica di maggiore precisione. Impostazione della precisione e utilizzoDecimal>può aiutare a mitigare gli errori in virgola mobile.