Drijvendekommagetal
Van Wikipedia
Een drijvendekommagetal (engels: floating point) is de digitale versie van een rationaal getal, maar wordt vaak gebruikt om een reëel getal voor te stellen.
Inhoud |
[bewerk] Het datatype
Het datatype wordt in wel real, float, single of double genoemd. Dit moet niet verward worden met fixed point types zoals 'decimal'. Reële getallen worden dikwijls gebruikt bij wetenschappelijk rekenen. Fixed point, of vastekomma, getallen zijn vooral nuttig bij financiële toepassingen. Reële getallen kunnen zeer hoge of lage waarden aannemen. Fixed point getallen vertonen beter afrondingsgedrag bij optellen en aftrekken.
Een drijvendekommagetal is een digitale representatie van een getal in een zekere subset van de rationale getallen en wordt vaak gebruikt in computers om een willekeurig reëel getal te benaderen. In het bijzonder representeert het een integer of vastekommagetal (de significant of mantisse), vermenigvuldigd met een basis verheven tot een zeker macht (de exponent). Een basis 2 is het binaire analogon van de wetenschappelijke notatie in basis 10.
(De Engelse uitdrukking floating point wordt hier vertaald met drijvende komma. Een andere gangbare vertaling is zwevende komma.)
Een drijvendekommaberekening is een rekenkundige bewerking met drijvendekommagetallen, waarbij vaak benadering of afronding nodig is omdat het resultaat van de bewerking niet exact te representeren is.
[bewerk] Eigenschappen van drijvendekommaberekeningen
Berekeningen met het drijvendekommagetalsysteem hebben twee belangrijke eigenschappen die verschillen van berekeningen met reële getallen.
Drijvendekommabewerkingen zijn niet associatief. Dat betekent dat in het algemeen voor drijvendekommegetallen x, y en z:
Drijvendekommabewerkingen zijn evenmin distributief: in het algemeen geldt:
Kort samengevat: een andere volgorde waarin drijvendekommabewerkingen worden uitgevoerd kan tot een ander resultaat van de berekening leiden. Dit is belangrijk in numerieke analyse, aangezien twee wiskundig equivalente formules in sommige gevallen niet hetzelfde numerieke resultaat zullen geven, waarbij de ene veel nauwkeuriger zou kunnen zijn dan de andere.
Om berekeningen met drijvendekommagetallen te versnellen is vaak een aparte Floating Point Unit aanwezig.
[bewerk] Interne codering
[bewerk] In het algemeen
Een drijvendekommagetal a kan worden gerepresenteerd door twee getallen m en e, waarbij a = m × be. In elk dergelijk systeem wordt een basis (of radix) b gekozen en een nauwkeurigheid p (het aantal cijfers dat moet worden opgeslagen). m (de significant of mantisse) is een p-cijferig getal van de vorm ±d.ddd...ddd (waarbij elk cijfer d een integer is uit het interval van 0 tot en met b−1). Als het eerste cijfer van m ongelijk is aan 0, wordt het getal genormeerd genoemd. Sommige systemen gebruiken een apart tekenbit (s, die −1 of +1 representeert) en vereisen dat m positief is, e is de exponent.
Deze methode maakt het mogelijk dat een groot bereik aan waardes wordt gerepresenteerd binnen een gegeven veldgrootte, wat niet mogelijk is in een vastekommanotatie.
Bijvoorbeeld, een drijvendekommagetal met vier decimale cijfers (b = 10, p = 4) en een exponentbereik van ±4 kan worden gebruikt om 43210, 4,321, of 0,0004321 te representeren, maar heeft niet genoeg nauwkeurigheid om 432,123 en 43212,3 te representeren (wat afgerond zou moeten worden tot 432,1 en 43210). Vanzelfsprekend is in de praktijk het aantal cijfers groter dan vier.
Voorts kennen drijvendekommarepresentaties vaak de bijzondere waarden +∞, −∞ (plus en min oneindig) en NaN ('Not a Number', geen getal). Oneindigheden worden gebruikt als de resultaten te groot zijn om te worden gerepresenteerd en NaN's geven een ongeoorloofde bewerking aan of een ongedefinieerde uitkomst.
[bewerk] IEEE 754
Het IEEE heeft ooit een standaard gezet (IEEE 754) voor het representeren van floating point getallen. Er is een enkele precisie (single) variant van 32 bits (1 tekenbit, 8 exponentbits en 23 mantissebits) en een dubbeleprecisie variant (double) van 64 bits (1+11+52). De waarde van het getal is gelijk aan: teken * mantisse * 2^exponent (waarbij * voor vermenigvuldigen staat en ^ voor machtverheffen). We leggen hier uit hoe de enkele precisievariant in detail werkt. De strekking van de dubbele precisie is hetzelfde.
[bewerk] Teken, exponent en mantisse
Het tekenbit is 1 voor een negatief getal en 0 voor een positief getal.
De exponent van 8 bits is gecodeerd met een offset van 127. Normaal representeren de 8 bits de getallen 0 (binair 00000000) tot en met 255 (11111111). Daar moet nu 127 vanaf getrokken worden. Dat wil zeggen dat nu de getallen -127 tot en met 128 weergegeven kunnen worden. Dus het getal 127 (01111111) betekent nu 0.
Het ingewikkeldst is de mantisse. Deze heeft in genormaliseerde toestand een hidden bit. Dit is lastig te bevatten, maar een in genormaliseerde real is het eerste bit altijd 1, anders zouden er meer manieren zijn om hetzelfde getal te representeren. Bijvoorbeeld het getal 5 zou gerepresenteerd kunnen worden als 0,5 * 10^1. Maar ook als 0,05 * 10^2. Dit is onwenselijk. Bij een genormaliseerd getal is het eerste getal achter de komma ongelijk aan nul. De mantisse moet zo groot mogelijk geschreven worden, maar kleiner dan 1.
In binaire vorm betekent dit dat het eerste getal achter de komma altijd 1 is, want het is immers ongelijk aan 0. Welnu, als het toch altijd 1 is, dan hoeven we het niet op te schrijven ook was de gedachte.
[bewerk] Het complete getal
We hebben nu een genormaliseerd getal in de vorm:
- sxxxxxxxxmmmmmmmmmmmmmmmmmmmmmmm
waarbij:
- teken = 1-210*s dus als s = 1 dan teken = -1; als s = 0 dan teken = 1
- exponent= xxxxxxxxxx2-12710
- mantisse= 0,1mmmmmmmmmmmmmmmmmmmmmmm2
De ondergeschreven 2-en en 10-en geven aan in welk talstelsel de waarden zijn genoteerd.
Het real-getal heeft de waarde:
- teken * mantisse * 210^exponent
[bewerk] Speciale waarden
Nu is het op deze manier niet mogelijk om het getal 0 te coderen. Om dit en nog wat andere speciale waarden, mogelijk te maken zijn er een aantal bitpatronen waarover een afspraak is.
Genormaliseerde getallen | 0<xxxxxxxx<25510, | mantisse > 0, | zoals hierboven beschreven |
Gedenormaliseerde getallen | xxxxxxxx=0, | mantisse > 0, | een soort integers |
Het getal 0 | xxxxxxxx=0, | mantisse = 0 | |
Oneindig | xxxxxxxx=25510, | mantisse = 0 | |
Not a number (NaN) | xxxxxxxx=25510, | mantisse > 0 |
Deze standaard wordt in bijna alle computers gebruikt. De waarde 'NaN' wordt gebruikt om het resultaat van een onmogelijke berekening te weer te geven, zoals een deling door nul. De waarde oneindig wordt gebruikt om resultaten weer te geven van berekeningen waarvan het resultaat te groot is om weer te geven, bijvoorbeeld een deling door een heel klein getal.
Alle speciale waarden hebben een positieve en een negatieve variant aangezien het tekenbit op zichzelf staat.
[bewerk] Bronnen
- Een bewerkte versie van het article What Every Computer Scientist Should Know About Floating-Point Arithmetic, door David Goldberg, gepubliceerd in het maartnummer van 1991 van Computing Surveys.
- David Bindels Annotated Bibliography over computerondersteuning voor wetenschappelijke berekeningen.
- Kahan, William & Darcy, Joseph (2001). How Java’s floating-point hurts everyone everywhere. Van http://www.cs.berkeley.edu/~wkahan/JAVAhurt.pdf(versie 5 september 2003).