Liukulukujen esitys tietokoneissa: binäärinen muoto, eksponentti ja tarkkuus

Liukulukujen esitys tietokoneissa: ymmärrä binäärimuoto, eksponentin rooli ja tarkkuusrajat — miten floating point vaikuttaa laskentaan ja aiheuttaa pyöristysvirheitä.

Tekijä: Leandro Alegsa

Binääriset reaaliluvut on tallennettava tietokoneeseen erityisellä tavalla. Tietokoneet esittävät numerot binäärisinä kokonaislukuina (kokonaisluvut, jotka ovat kahden potensseja), joten ne eivät voi suoraan esittää muita kuin kokonaislukuja, kuten desimaalilukuja, koska radix-pistettä ei ole. Yksi tapa, jolla tietokoneet kiertävät tämän ongelman, on liukulukujen esittäminen, jossa "liukuluku" viittaa siihen, että radix-piste voi siirtyä ylös- tai alaspäin, kun se kerrotaan eksponentilla (potenssilla).


 

Laajentaen: liukulukuesityksessä luku tallennetaan yleensä kolmessa osassa: etumerkki, eksponentti ja signifikaandi (joskus kutsutaan mantissaksi). Tavallisin standardi on IEEE 754, jota useimmat modernit kielet ja alustat noudattavat. Perusperiaate on seuraava:

Perusrakenne

  • Etumerkki (sign): yksi bitti kertoo, onko luku positiivinen vai negatiivinen.
  • Eksponentti: joukko bittejä, joka ilmaisee kymmenien sijaan binäärisen siirron eli kuinka monta kertaa radix (kaksi) korotetaan. Eksponentti tallennetaan usein ns. bias-arvolla (siirretty arvo), jotta negatiiviset eksponentit saadaan edustettua.
  • Signifikaandi (mantissa): kertoo luvun tarkat binääritarkat merkit. Normalisoiduissa luvuissa johtava bitti on oletettu 1 eikä sitä tallenneta erikseen ("implicit leading 1").

IEEE 754 -esimerkkejä

  • Single (32-bittiä): 1 bitti signille, 8 bittiä eksponentille, 23 bittiä fraction (signifikaandin tallennettu osa). Totta merkittävyysbittien määrä on 24 (sisältää implisiittisen 1). Antaa noin 7 desimaalin tarkkuuden.
  • Double (64-bittiä): 1 bitti signille, 11 bittiä eksponentille, 52 bittiä fraction. Totta merkittävyysbittien määrä on 53. Antaa noin 15–17 desimaalin tarkkuuden.

Arvon laskukaava

Normaalille (normalisoidulle) liukuluvulle arvo lasketaan kaavalla:

arvo = (−1)^s × 1.f × 2^(e − bias)

Missä s on etumerkki, f on fraction-kentän binääripilkku (esim. .101...), e on tallennettu eksponentti ja bias on eksponentin siirtoarvo (esim. single: bias = 127, double: bias = 1023).

Erikoistapaukset

  • Nolla: eksponentti = 0 ja fraction = 0. IEEE 754 erottaa +0 ja −0, vaikka ne yleensä käyttäytyvät samankaltaisesti aritmetiikassa.
  • Subnormaalit (denormaalit): eksponentti = 0 ja fraction ≠ 0. Näillä voidaan edustaa hyvin pieniä lukuja lähempänä nollaa, mutta ilman johtavaa 1:stä (arvo = (−1)^s × 0.f × 2^(1 − bias)).
  • Inf (ääretön): eksponentti kaikki 1 ja fraction = 0 → positiivinen tai negatiivinen ääretön riippuen etumerkistä.
  • NaN (Not a Number): eksponentti kaikki 1 ja fraction ≠ 0 → epämääräinen/virhearvo, esim. 0/0 tai epäkelpo operaatio.

Tarkkuus ja rajoitukset

  • Monet desimaaliluvut eivät ole tarkasti esitettävissä binäärissä. Esimerkiksi 0.1 desimaalina on toistuva binäärijakso (0.0001100110011...), joten se tallennetaan likimääräisenä arvoa lähellä olevaan binäärimuotoon.
  • Pienet pyöristysvirheet kertyvät aritmetiikassa; näet eroja etenkin monissa summaus- tai toistuvissa laskutoimituksissa.
  • Vertailu suoraan equality (==) on epäluotettava liukuluvuilla — käytä erotuksen absoluuttia arvoa ja hyväksyttyä epsilon-arvoa tai muita algoritmeja (esim. suhteellinen virheraja).

Pyöristys, ylivuoto ja alivuoto

  • Pyöristys: IEEE 754 määrittelee useita pyöristysmoodia (round to nearest, toward zero, toward +inf, toward −inf). Usein käytössä on "round to nearest, ties to even".
  • Ylivuoto (overflow): kun laskun tulos on suurempi kuin suurin edustettavissa oleva arvo → usein arvo muuttuu ±Inf:ksi.
  • Alivuoto (underflow): hyvin lähellä nollaa olevat tulokset voivat muuttua subnormaaleiksi tai nollaksi, mikä johtaa menetykseen tarkkuudessa.

Käytännön huomioita ja hyviä käytäntöjä

  • Käytä oikeaa tarkkuutta: rahan käsittelyssä suositaan usein desimaalitietotyyppejä (decimal) tai kokonaislukupohjaista esitystä (esim. sentteinä), ei doublea suoraan.
  • Vältä suoraa vertailua liukuluvuissa; käytä epsilon-vertailua tai muuta soveltuvaa normia.
  • Jos tarvitset numeerisesti stabiileja summauksia, harkitse Kahanin summamenetelmää tai muita tarkkuutta parantavia algoritmeja.
  • Tarkenna tulostusmuotoilua, jotta et tulosta liikaa merkkejä, jotka vain paljastavat esityksen likiarvon hienovaraisuuden.

Yhteenveto

Liukulukuesitys antaa tehokkaan ja laajasti käytetyn tavan edustaa reaalilukuja tietokoneissa, mutta se ei ole eksakti desimaalien kannalta. On tärkeää ymmärtää eksponentin ja signifikaandin roolit, pyöristysvaikutukset sekä erikoistapaukset (NaN, Inf, subnormaalit) suunniteltaessa numerisia algoritmeja tai käsiteltäessä arkirahoja ja tieteellisiä laskelmia.

Yleiskatsaus

Matematiikassa ja luonnontieteissä hyvin suuria ja hyvin pieniä lukuja yksinkertaistetaan usein ja kerrotaan potenssilla kymmenen, jotta niitä olisi helpompi ymmärtää. Esimerkiksi 1,2 biljoonaa voi olla paljon helpompi lukea muodossa {\displaystyle 1.2\times 10^{12}} kuin 1 200 000 000 000. Tätä voidaan käyttää myös negatiivisten kymmenkertaisten potenssien kanssa pienten lukujen muodostamiseen, eli 0,000001 voidaan esittää muodossa {\displaystyle 1\times 10^{-6}}. Tätä prosessia kutsutaan tieteelliseksi merkintätavaksi.

Koska tietokoneet rajoittuvat kokonaislukuihin ja binäärilukuihin, ne eivät voi helposti esittää murtolukuja desimaalilukuina. Murtolukujen esittämiseksi tietokoneet käyttävät kolmea binäärilukusarjaa tieteellisen merkintätavan esitykseen. Ne ovat: merkkibitti, joka määrittää, onko luku positiivinen (0) vai negatiivinen (1); merkitsevä, joka on kokonaislukuversio luvusta; ja eksponentti, joka on potenssi, jolla perusluku kerrotaan.

Significand

Merkkipaalu löytyy ottamalla luku ja siirtämällä radix-pistettä, kunnes siinä ei ole murto-osaa, jolloin siitä tulee kokonaisluku. Desimaalilukuna tämä tarkoittaa, että 1,45:stä tehdään 145 siirtämällä pistettä 2 askelta oikealle, ja binäärilukuna tämä tarkoittaa, että 1101,0111 (13,4375) tehdään 1101 0111 (215) siirtämällä pistettä 4 askelta oikealle; molemmissa tapauksissa nämä luvut eivät liity toisiinsa muuten kuin käyttämällä samoja numeroita samanlaisessa järjestyksessä.

Samoin kuin tieteellisessä merkintätavassa merkitsevä on mahdollisimman yksinkertainen, liukuluvuissa siitä pyritään tekemään kokonaisluku, jotta se voidaan esittää tavuina ja käyttää laskutoimituksissa.

Eksponentti

Eksponentti on numeroiden määrä, jonka radix-piste on siirtynyt: jos se siirtyy vasemmalle, eksponentti on negatiivinen, mutta jos se siirtyy oikealle, se on positiivinen. Kuten edellä, 1,45:n muuttaminen 145:ksi edellyttää kertomista 100:lla, joten eksponentti on 2, koska {\displaystyle 100=10^{2}}. Vastaavasti 1101.0111 (13.4375) muuttaminen 1101 0111 (215) -luvuksi edellyttää radix-pisteen siirtämistä neljä saraketta oikealle, joten eksponentti on 4; tämä voidaan todentaa desimaalilukuna seuraavasti: {\displaystyle 215\div 13.4375=16(2^{4})} .

Koska prosessi on käänteinen useimpiin tieteellisen merkintätavan tapauksiin verrattuna, koska siinä tehdään murtoluvusta kokonaisluku sen sijaan, että käännetään suuri kokonaisluku murtoluvuksi, eksponentit ovat yleensä negatiivisia desimaalipisteen siirtämiseksi vasemmalle; desimaalilukuna tämä tarkoittaisi, että kokonaisluku 145 käännetään takaisin murtoluvuksi 1.45 kertomalla se luvulla {\displaystyle 10^{-2}}. Sen sijaan, että eksponentissa käytettäisiin allekirjoitettua vasemmanpuoleisinta bittiä, eksponentti on sen sijaan vinoutettu, jolloin 32-bittisten liukulukujen eksponenttien vaihteluväli on {\displaystyle 2^{-126}} ja {\displaystyle 2^{127}}. Vääristetyn eksponentin lähtöarvo saadaan lisäämällä siihen 127:

{\displaystyle b^{5}=132(5+127)=10000100}

{\displaystyle b^{-5}=122(-5+127)=01111010}

{\displaystyle b^{0}=127(0+127)=01111111}



 

Esimerkki

Desimaaliluku to Kaksoisluku

Oletetaan esimerkiksi, että haluamme esittää desimaaliluvun 37,40625 sen binäärisen vastakohdan eli bikimaaliluvun (tai binäärisen desimaaliluvun/-murtoluvun). Ensin meidän on muunnettava desimaalilukumme, joka on 10:n potensseja, binääriluvuksi, joka on 2:n potensseja. Yksi tapa tehdä tämä on vähentää suurin mahdollinen kahden potenssi, kunnes saavutetaan nolla:

{\displaystyle 37.40625-\mathbf {32} (2^{5})=5.40625}

{\displaystyle 5.40625-\mathbf {4} (2^{2})=1.40625}

{\displaystyle 1.40625-\mathbf {1} (2^{0})=0.40625}

{\displaystyle 0.40625-\mathbf {0.25} (2^{-2})=0.15625}

{\displaystyle 0.15625-\mathbf {0.125} (2^{-3})=0.03125}

{\displaystyle 0.03125-\mathbf {0.03125} (2^{-5})=0}

Käyttämällä edellä mainittuja kahden potensseja voimme esittää desimaalilukumme {\displaystyle 37.40625} seuraavasti:

Teho:

{\displaystyle 2^{5}}

{\displaystyle 2^{4}}

{\displaystyle 2^{3}}

{\displaystyle 2^{2}}

{\displaystyle 2^{1}}

{\displaystyle 2^{0}}

-

{\displaystyle 2^{-1}}

{\displaystyle 2^{-2}}

{\displaystyle 2^{-3}}

{\displaystyle 2^{-4}}

{\displaystyle 2^{-5}}

Arvo:

1

0

0

1

0

1

-

0

1

1

0

1

Bicimal to Float

Olemme varmistaneet, että desimaalilukumme {\displaystyle 37.40625} esitetään binäärilukuna {\displaystyle 100101.01101} . Tietokoneiden ongelmana on kuitenkin se, että ne esittävät luvut kokonaislukujen potensseina bittien avulla, mikä tekee murtoluvuista ja negatiivisista luvuista monimutkaisia. IEEE-754:n mukaisesti tämä tehdään tietokoneella yleensä siten, että luodaan 32-bittinen liukuluku, joka koostuu kolmesta osasta: merkistä, 1 bitti, jolla määritetään, onko luku positiivinen vai negatiivinen; eksponentista, 8 bittiä, jolla esitetään eksponentti ja johon lisätään 127, jotta vältytään merkityiltä tavuilta; ja merkkialkiosta, joka on binäärilukumme ilman kaksoispistettä, joka jakautuu 23 bittiin. Koska meidän on siirrettävä kaksoispisteemme 5 paikkaa, jotta {\displaystyle 100100.01101} muuttuu merkitseväksi {\displaystyle 10010001101} , eksponenttimme on {\displaystyle 132(5+127)} . Käyttämällä 32-bittistä liukulukua voimme esittää 37,40625 näin:

Tyyppi:

±

Eksponentti

Significand

Arvo:

0

1

0

0

0

0

1

0

0

0

0

1

0

1

0

1

1

0

1

0

0

0

0

0

0

0

0

0

0

0

0

0

Merkitys:

+

{\displaystyle 2^{7}+2^{2}=132}

{\displaystyle 2^{20}+2^{18}+2^{16}+2^{15}+2^{13}=1,417,216}



 

Aiheeseen liittyvät sivut

 

Kysymyksiä ja vastauksia

K: Mitä ovat reaaliluvut?


V: Reaaliluvut ovat mitä tahansa lukua, joka voidaan ilmaista desimaalilukuna, mukaan lukien murtoluvut ja irrationaaliluvut.

K: Miten tietokoneet tallentavat binäärilukuja?


V: Tietokoneet tallentavat binääriluvut binäärisinä kokonaislukuina, jotka ovat kokonaislukuja, jotka ovat kahden potensseja.

K: Voivatko tietokoneet esittää suoraan muita kuin kokonaislukuja, kuten desimaalilukuja?


V: Ei, tietokoneilla ei ole suoraa tapaa esittää muita kuin kokonaislukuja kuin desimaalilukuja, koska radix-pistettä ei ole.

K: Mikä on liukulukujen esittämisen tarkoitus?


V: Liukulukujen esittämisen avulla tietokoneet voivat kiertää radix-pisteen puuttumisesta johtuvan ongelman sallimalla radix-pisteen siirtymisen ylemmäs tai alemmas, kun se kerrotaan eksponentilla (potenssilla).

K: Mitä "kelluva" tarkoittaa kelluvan pisteen esityksessä?


V: Termi "kelluva" viittaa siihen, että radix-piste voi liikkua korkeammalle tai matalammalle, kun se kerrotaan eksponentilla (potenssilla).

K: Miten eksponentti (potenssi) lasketaan?


V: Eksponentti (potenssi) lasketaan kertomalla perusluku itsellään tietty määrä kertoja. Esimerkiksi 2^3 = 8, koska 2 x 2 x 2 x 2 = 8.


Etsiä
AlegsaOnline.com - 2020 / 2025 - License CC3