logo

Pythonin float-alue

Pythonissa, kelluntavalikoima arvot riippuvat toteutuksesta ja alustasta. Python-kielimääritys vaatii vain sen liukuluku numerot tukevat ainakin 1e-308 kohtaan 1e+308 vähintään tarkkuudella 53 bittiä .

Käytännössä useimmat nykyaikaiset Python-toteutukset käyttävät IEEE 754 liukulukustandardi, joka tarjoaa vaihteluvälin noin 1.7e-308 kohtaan 1,7e+308 tarkkuudella 53 bittiä . Tämä alue on sama kaikilla alustoilla, ja sitä tukee sisäänrakennettu kelluva tyyppi.

On kuitenkin tärkeää huomata, että liukulukuaritmetiikka on alttiina pyöristysvirheille ja muille epätarkkuuden lähteille, erityisesti suoritettaessa operaatioita erittäin suurille tai hyvin pienille luvuille. Se voi joissakin tapauksissa johtaa odottamattomaan käyttäytymiseen ja virheisiin.

Näiden ongelmien välttämiseksi on usein suositeltavaa käyttää desimaali tai kiinteä piste aritmeettinen työskenneltäessä rahallisten arvojen tai muiden suurta tarkkuutta vaativien sovellusten kanssa. The desimaalimoduuli Pythonissa tukee kiinteän pisteen aritmetiikkaa konfiguroitavalla tarkkuudella ja on hyvä vaihtoehto liukulukuaritmetiikalle näissä sovelluksissa.

ketjutus java-merkkijono

The IEEE 754 standardi määrittää liukulukujen alueen ja tarkkuuden, joita useimmat nykyaikaiset ohjelmointikielet, mukaan lukien Python, käyttävät. Standardi määrittelee kaksi perusmuotoa liukulukuille:

    Yhden tarkkuuden muoto

Se käyttää 32 bittiä ja tarjoaa noin 7 desimaalin tarkkuudella tarkkuuden numeroita.

    Kaksinkertainen tarkkuusmuoto

Se käyttää 64 bittiä ja tarjoaa noin 16 desimaalin tarkkuudella tarkkuuden numeroita.

Python käyttää kaksinkertainen tarkkuus oletuksena liukulukuluvut, mikä tarkoittaa, että liukulukujen alue on likimääräinen 1.7e-308 kohtaan 1,7e+308 tarkkuudella 53 bittiä . Tämä alue määräytyy maksimi- ja minimieksponenttien mukaan, jotka voidaan esittää käyttämällä 11 bittiä , yhdistettynä enimmäis- ja minimimerkityksiin (eli luvun murto-osaan), jotka voidaan esittää käyttämällä 52 bittiä .

Liukulukuaritmeetiikan todelliseen tarkkuuteen voivat vaikuttaa monet tekijät, mukaan lukien tapa, jolla numerot tallennetaan muistiin, operaatioiden järjestys ja pyöristystavan valinta. Se voi joissakin tapauksissa johtaa hienovaraisiin pyöristysvirheisiin ja muihin epätarkkuuden lähteisiin.

Näiden ongelmien välttämiseksi on usein suositeltavaa käyttää vaihtoehtoisia lähestymistapoja, kun työskennellään erittäin suurilla tai pienillä lukumäärillä tai kun vaaditaan suurta tarkkuutta. Esimerkiksi:

  1. Käyttää kiinteän pisteen aritmetiikka tai desimaaliaritmetiikka , joka tarjoaa kiinteän määrän desimaaleja tarkkuudella ja välttää pyöristysvirheet.
  2. Käyttää mielivaltainen tarkkuus kirjastot kuten 'mpmath' tai 'gmpy2' , joiden avulla voit suorittaa laskelmia erittäin tarkasti ja välttää pyöristysvirheet.

Yksi tärkeä huomioitava seikka on, että kun suoritat aritmeettisia operaatioita liukulukuluvuille Pythonissa, saatat kohdata odottamatonta toimintaa, joka johtuu liukulukuaritmeettisen toiminnan tavasta.

Jotkut aritmeettiset operaatiot voivat johtaa hyvin pieniin tai erittäin suuriin lukuihin, joita ei voida esittää tarkasti liukulukuaritmetiikalla. Näissä tapauksissa tulos voi olla pyöristetty tai katkaistu , mikä johtaa odottamattomaan toimintaan tai epätarkkuuksiin laskelmissasi.

Liukulukuaritmetiikka ei ole assosiatiivista , mikä tarkoittaa, että toimintojen suoritusjärjestys voi vaikuttaa tulokseen. Esimerkiksi, (a + b) + c ei välttämättä ole yhtä suuri kuin a + (b + c) pyöristysvirheiden ja muiden epätarkkuuden syiden vuoksi.

Liukulukuaritmetiikka ei myöskään ole jakavia , mikä tarkoittaa sitä (a + b) * c ei välttämättä ole yhtä suuri kuin a * c + b * c pyöristysvirheiden ja muiden epätarkkuuden syiden vuoksi. Näiden ongelmien vaikutusten minimoimiseksi on usein suositeltavaa käyttää matemaattista moduulia tai muita numeerisia kirjastoja, jotka tarjoavat toimintoja aritmeettisten operaatioiden suorittamiseen liukulukuille tarkemmin ja luotettavammin. On myös hyvä käytäntö välttää liukulukujen vertailua tasa-arvoa varten ja käyttää sen sijaan toleranssikynnystä tai muita menetelmiä kahden arvon välisen eron suuruuden vertailuun.

Esimerkki:

Otetaan esimerkki näyttääksesi kuinka liukulukuaritmetiikka voi johtaa odottamattomaan käyttäytymiseen pythonissa:

 a = 0.1 b = 0.2 c = 0.3 result1 = (a + b) + c result2 = a + (b + c) print(result1) print(result2) 

Lähtö:

 0.6000000000000001 0.6 

Selitys:

Tässä esimerkissä suoritamme kaksi erilaista laskutoimitusta käyttämällä samoja arvoja a, b, ja c . Ensimmäisessä laskelmassa lisäämme a ja b ensin ja lisää sitten tulos kohtaan c . Toisessa laskelmassa lisäämme b ja c ensin ja lisää sitten tulos kohtaan a .

Saatamme odottaa näiden kahden laskelman tuottavan saman tuloksen, koska ne käyttävät samoja arvoja a, b , ja c . Kuitenkin liukulukuaritmeettisten rajoitusten vuoksi nämä kaksi laskelmaa tuottavat hieman erilaisia ​​tuloksia.

Ensimmäinen laskelma tuottaa tuloksen 0,6000000000000001 , kun taas toinen laskutoimitus tuottaa tuloksen 0.6 . Tämä johtuu siitä, että ensimmäisen laskelman välitulokset poikkeavat hieman toisen laskennan välituloksista pyöristysvirheiden ja muiden epätarkkuuden lähteiden vuoksi.

Näiden ongelmien välttämiseksi on usein suositeltavaa käyttää desimaalimoduuli tai muita suoritustapoja aritmeettiset operaatiot päällä liukuluku numerot tarkemmalla ja luotettavammalla tavalla.

Esimerkiksi:

 import decimal a = decimal.Decimal('0.1') b = decimal.Decimal('0.2') c = decimal.Decimal('0.3') result1 = (a + b) + c result2 = a + (b + c) print(result1) print(result2) 

Lähtö:

 0.6 0.6 

Selitys:

Tässä esimerkissä käytämme desimaalimoduuli suorittaaksesi samat laskelmat käyttämällä kiinteä piste aritmeettinen tarkkuudella 1 desimaalin paikka. Sen avulla voimme välttää pyöristysvirheet ja muut epätarkkuuden lähteet, jotka voivat vaikuttaa liukuluku aritmeettinen. Tämän seurauksena molemmat laskelmat tuottavat saman tuloksen 0.6 .