**Liukuluku** on tietokoneissa käytetty reaalilukujen likimääräinen sisäinen esitysmuoto. Liukulukumuoto on kompromissi tarvittavien bittien lukumäärän, luvun esitystarkkuuden ja peitettävän lukualueen välillä.

Liukulukulaskenta
-----------------

Liukulukuun kuuluu neljä osaa: etumerkki ({\displaystyle s}), mantissa ({\displaystyle m}), kantaluku ({\displaystyle k}) ja eksponentti ({\displaystyle c}). Etumerkki kertoo, onko luku negatiivinen vai positiivinen. Mantissa kuvaa luvun merkitseviä numeroita. Kantaluku ja eksponentti määrittävät luvun suuruusluokan. Tällöin liukuluvun arvoksi {\displaystyle x} saadaan:

{\displaystyle x=(-1)^{s}mk^{c}}
Esitys ei kuitenkaan ole yksikäsitteinen lukunelikolle {\displaystyle (s,m,k,c)} ellei lukualueita rajata tarkasti. Yksikäsitteisyys voidaan saavuttaa sopimalla tietty kantaluku {\displaystyle k}, ja sen jälkeen vaatimalla, että {\displaystyle {\frac {1}{k}}\leq m<1} ja {\displaystyle c=\lfloor \log \_{k}|x|\rfloor +1}. Tietokoneissa pätee yleensä {\displaystyle k=2}, jolloin {\displaystyle {\frac {1}{2}}\leq m<1} ja {\displaystyle c=\lfloor \log \_{2}|x|\rfloor +1}.

Liukulukulaskenta voidaan aina toteuttaa ohjelmallisesti mutta monet suorittimet pystyvät suoraan liukulukulaskentaan matematiikkasuorittimella. Käyttäjälle tämä näkyy vain nopeuserona, ei tulosten erona. Matematiikkasuoritin on ollut erillinen apusuoritin varsinaisen suorittimen rinnalla, mutta se on nykyään integroitu varsinaisen suorittimen kanssa samalle piirisirulle. 
Esimerkiksi IBM PC -yhteensopivissa käytetty vuonna 1989 julkaistu Intel i486 integroi matemaattisuorittimen samalle piisirulle.

Johdatteleva esimerkki
----------------------

Oletetaan kantaluvun olevan 10, mantissan kolminumeroinen ja eksponentissa olevan etumerkin ja yhden numeron.

Tällöin suurin esitettävissä oleva luku on {\displaystyle 999\times 10^{9}}. Alempana selitettävistä normaaleista luvuista pienin nollaa suurempi on {\displaystyle 100\times 10^{-9}}, pienin epänormaali luku {\displaystyle 001\times 10^{-9}}. Tarkkuus riippuu suuruusluokasta: välillä 1–10 luvut esitetään tuhannesosan tarkkuudella, välillä 10–100 sadasosan tarkkuudella ja niin edelleen.

Kullekin luvulle on kolme eri esitystapaa: esimerkiksi {\displaystyle 1,23} voidaan esittää {\displaystyle 123\times 10^{-2}}, {\displaystyle 012\times 10^{-1}} tai {\displaystyle 001\times 10^{0}}. Esitystavoista ensimmäinen on tarkin, ja tätä esitystapaa kutsutaan normaaliksi; siis normaalin luvun mantissa on aina vähintään {\displaystyle 100} ja enintään {\displaystyle 999}.

Normaalit luvut muodostavat näin nollaa kohti tihentyvän parven, jossa kuitenkin nollan ympärillä on aukko: Pienin positiivinen luku on tuhat kertaa suurempi kuin sen erotus toiseksi pienimpään positiiviseen lukuun. Epänormaalit luvut täyttävät tämän aukon: tarkkuus pienenee, mutta laskenta ei "romahda" äkillisesti nollaan.

IEEE 754 -liukulukustandardi
----------------------------

IEEE 754 on yleisin tietokoneissa käytetty liukulukustandardi. Se olettaa kantaluvuksi {\displaystyle k=2}. Etumerkki ilmoitetaan yhdellä bitillä. {\displaystyle s=0} tarkoittaa positiivista lukua, ja {\displaystyle s=1} tarkoittaa negatiivista. Mantissa ja eksponentti ovat etumerkittömiä bittijonoja. Standardi määrittelee neljä erilaista liukulukua:

* Perustarkkuus ({\displaystyle m} on 23 bittiä ja {\displaystyle c} on 8 bittiä)
* Kaksoistarkkuus ({\displaystyle m} on 52 bittiä ja {\displaystyle c} on 11 bittiä)
* Laajennettu perustarkkuus ({\displaystyle m} on 31 bittiä ja {\displaystyle c} on 11 bittiä)
* Laajennettu kaksoistarkkuus ({\displaystyle m} on 63 bittiä ja {\displaystyle c} on 15 bittiä)

Laajennettua kaksoistarkkuutta kutsutaan joskus 80-bittiseksi muodoksi, mutta laitetoteutukset eivät tyypillisesti käytä piilotettua bittiä ja se voidaan merkitä 79-bittiseksi.

IEEE 754 standardin lisäksi on IEEE 854 -standardi, joka ei määrittele miten liukuluvut koodataan biteiksi, mutta se sallii sekä kymmen- että kaksikantaiset muodot.

### Normalisoidut luvut

Kun {\displaystyle c\neq 0}, luku on normalisoitu. Tällöin
yksikäsitteisyys saavutetaan sopimalla {\displaystyle 1\leq m\_{IEEE}<2} ja {\displaystyle c\_{IEEE}=\lfloor \log \_{2}|x|\rfloor }. Tällöin liukuluvun arvoksi {\displaystyle x} saadaan:

{\displaystyle x=(-1)^{s}m\_{IEEE}2^{c\_{IEEE}}}
Lukua nolla ei voi esittää suoraan johtuen {\displaystyle m\_{IEEE}} määritelmästä, koska ylin bitti säädetään kiinteästi ykköseksi. Standardin mukaan luku on nolla kun {\displaystyle m=c=0}. Tämän seurauksena luvun nolla esitys tietokoneen muistissa on kaikki bitit nollina, mikä nopeuttaa liukulukumuuttujien alustamista eräissä tietokonejärjestelmissä.

Normalisoidussa muodossa mantissan ensimmäinen luku on aina 1b, joten se jätetään pois ja siten saadaan käyttöön yksi numero enemmän tarkkuutta. Täten {\displaystyle m\_{IEEE}=1.m}

Koska yksi eksponentin arvo on varattu nollalle, ei eksponentteja voi esittää suoraan, vaan eksponentti on IEEE-liukuluvuissa tallennettu muodossa jota kutsutaan nimillä *offset binary* tai *biased exponent*. Tämä {\displaystyle c\_{IEEE}=c-b}, missä {\displaystyle b} riippuu käytetystä tarkkuudesta. Perustarkkuudelle {\displaystyle b=127} ja kaksoistarkkuudella {\displaystyle b=1023}. Eksponentti voi täten esittää suuremman määrän positiivisia arvoja kuin negatiivisia arvoja.

### Ei-normalisoidut arvot

Kun {\displaystyle c=0} ja {\displaystyle m\neq 0}, luku ei ole normalisoitu. Tällöin {\displaystyle m\_{IEEE}=0.m} ja {\displaystyle c\_{IEEE}=b}, missä {\displaystyle b} riippuu käytetystä tarkkuudesta. Perustarkkuudelle {\displaystyle b=-126} ja kaksoistarkkuudella {\displaystyle b=-1022}.

### Äärettömät: positiivinen ja negatiivinen

IEEE-745 määrittelee myös positiivisen ja negatiivisen äärettömän. Käsitteellisesti ne eivät vastaa niinkään matemaattista äärettömyyttä vaan mitä tahansa lukua, joka ylittää tai alittaa esitettävissä olevien lukujen alueen. Äärettömilläkin voidaan osittain laskea, esimerkiksi mikä tahansa positiivinen normaali luku jaettuna positiivisella äärettömällä antaa tulokseksi positiivisen nollan.

### Nollat: positiivinen ja negatiivinen

Analogisesti äärettömien kanssa nollia on kaksi, positiivinen ja negatiivinen. Ne kuvaavat paitsi matemaattisen tarkkaa nollaa, myös lukuja joiden suuruus alittaa ei-normalisoitujen lukujenkin esitettävissä olevat arvot.

### Epäluku ("Not-a-Number", NaN)

Lopuksi standardi määrittelee tuloksen laskutoimitukselle, jolle ei ole mielekästä vastausta edes äärettömien tai nollien avulla esitettynä. Esimerkiksi positiivisen ja negatiivisen äärettömän summa on tällainen: taustalla on ajatus, jonka mukaan emme tiedä kumpi ääretön on suurempi, joten mikään vastaus ei kelpaa. Jokaisen luvun jokainen laskutoimitus epäluvun kanssa tuottaa epäluvun: esimerkiksi epäluku kertaa nolla *ei* ole nolla vaan epäluku.

Epälukujen ja osittain myös äärettömien ja nollien avulla pitkä laskenta voidaan tehdä loppuun ja vasta lopuksi tutkia miltä osin saatiin mielekkäitä tuloksia ja milloin esimerkiksi jokin laskukaava ei toiminut.

### Laskutaulukot

Seuraavassa "S" kuvaa suurta lukua, joka on lähes lukualueen ylärajalla, luku 3 on esimerkki tavallisesta luvusta, äärettömät on merkitty +inf ja −inf, nollat +0 ja −0, ja epäluku on NaN.

Yhteenlasku| + | 3 | S | +inf | −inf | +0 | −0 | NaN |
| --- | --- | --- | --- | --- | --- | --- | --- |
| 3 | 6 | S | +inf | −inf | 3 | 3 | NaN |
| S |  | +inf | +inf | −inf | S | S | NaN |
| +inf |  |  | +inf | NaN | +inf | +inf | NaN |
| −inf |  |  |  | −inf | −inf | −inf | NaN |
| +0 |  |  |  |  | +0 | −0 | NaN |
| −0 |  |  |  |  |  | −0 | NaN |
| NaN |  |  |  |  |  |  | NaN |

### Ominaisuuksia

* Kahta normalisoitua IEEE-754 lukua voi verrata suoraan käyttämällä kahden komplementin lukujen vertailijaa.

### Esimerkki

Luvun {\displaystyle 1} esitys perustarkkuudella tarkoittaa lukua, jossa {\displaystyle m=0} ja {\displaystyle c=127}, eli heksadesimaalijonona: 3f80 0000. Sama luku kaksoistarkkuudella saa esitysmuodon: 3ff0 0000 0000 0000. Luvun {\displaystyle -1} esitysmuoto perus- ja kaksoistarkkuudella on bf80 0000 ja bff0 0000 0000 0000.

### Muut liukulukumuodot

*binary16* on (*puolitarkkuus*, engl. *half-precision*) on *binary32* muodosta typistetty 16-bittinen muoto, joka on suunnattu muun muassa vähävirtaisissa laitteissa käytettäväksi. 16-bittistä muotoa käytetään myös "syvävärikuvien" (engl. *Deep Color*) tallentamiseen OpenEXR-muodossa.

On myös julkaistu erilaisia epästandardeja liukulukumuotoja kuten Nvidian TensorFloat-32.

16-bitin puolitarkkuutta käytetään esimerkiksi neuroverkkojen koulutuksessa.

Epätarkkuuksia ja ongelmia
--------------------------

Kuten murtoluvut voidaan esittää päättyvinä kymmenkantaisina desimaalilukuina vain jos nimittäjä on kymmenen potenssi, voidaan luku esittää tarkasti liukulukuna vain, jos vastaavan murtolukuesityksen nimittäjä on kahden potenssi.
Siten esimerkiksi desimaalilukua 0,1 ei voi esittää tarkasti liukulukuna.

Esimerkiksi JavaScriptin vertailu `0.1 + 0.2 === 0.3` on epätosi, koska sitä evaluoitaessa luvut on pyöristetty kolme kertaa ja summalausekkeen tulos on eri kuin luvun 0,3 muunnos liukuluvuksi.

JavaScriptissa, jossa kaikki luvut tallennetaan kaksoistarkkuuden 64-bittisinä IEEE-liukulukuina, suurin turvallisesti esitettävä kokonaisluku on 9007199254740992 (Number.MAX\_SAFE\_INTEGER+1). Esimerkiksi vertailu `9007199254740991 + 1 === 9007199254740991 + 2` palauttaa toden, vaikka on matemaattisesti epätosi.

On huomattava että tietokoneiden käsittelemät liukuluvut on optimoitu teknis-tieteellisen laskennan tarkoituksiin. IEEE754-standardin suunnittelija William Kahan valitsi 53 bitin tarkkuuden liukuluvuille, jotta tieteellisessä laskennassa vältettäisiin vaativa virheanalyysin tarve. Standardin mukaiset liukuluvut eivät sovellu lainkaan finanssimatematiikan käyttöön, sillä useimpia yksinkertaisiakaan desimaalilukuja ei voi tarkasti ilmoittaa liukulukuina, mikä johtaa pyöristysvirheisiin. Lisäksi suurissa summissa arvoalue voi loppua kesken. Tätä varten on kehitetty ns. desimaaliset liukuluvut. Näiden käsittely tietokoneen laitteistolla sisältyy vain muutamiin mainframe-koneisiin, kuten IBM z-Series, joten laskenta tapahtuu yleensä ohjelmallisesti. Finanssimatematiikan luonteen vuoksi tämän hitaus ei yleensä ole ongelma.

Katso myös
----------

* Kokonaisluku (tietotekniikka)
* Binäärijärjestelmä
* Komplementti (tietotekniikka)

Lähteet
-------

1. 1 2  David Goldberg: What Every Computer Scientist Should Know About Floating-Point Arithmetic  maaliskuu 1991.  Arkistoitu. Viitattu 24.2.2023. (englanniksi)
2. ↑  Michael F. Cowlishaw: Decimal Floating-Point: Algorism for Computers (PDF) *speleotrove.com*. Viitattu 24.2.2023. (englanniksi)
3. ↑  A Transprecision Floating-Point Platform for Ultra-Low Power Computing *arxiv.org*.  28.11.2017. doi:10.23919/DATE.2018.8342167.  Viitattu 22.1.2021. (englanniksi)
4. ↑  Interpreting OpenEXR Deep Pixels *openexr.com*. Viitattu 23.3.2024. (englanniksi)
5. ↑  TensorFloat-32 in the A100 GPU Accelerates AI Training, HPC up to 20x *blogs.nvidia.com*.  14.5.2020. Viitattu 22.1.2021. (englanniksi)
6. ↑  Dylan Martin: Cerebras's supercomputer has more cores than world's fastest iron – with a big catch *theregister.com*.  15.11.2022. Viitattu 16.11.2022. (englanniksi)
7. ↑  The simple math behind decimal-binary conversion algorithms *blog.angularindepth.com*.  [vanhentunut linkki]
8. ↑  Here is what you need to know about JavaScript’s Number type *medium.com*.
9. ↑

Aiheesta muualla
----------------

* What Every Computer Scientist Should Know About Floating-Point Arithmetic – Internet Archive
* Tietoja IEEE 754 -standardista (Arkistoitu – Internet Archive) (englanniksi)