Op deze pagina, ga je leren hoe computers niet-hele getallen opslaan.
De manier waarop computers getallen op slaan die niet heel zijn heet zwevendekommagetal.
De decimale vertegenwoordiging van ⅓ is 0,33333... Het bevat oneindig veel cijfers dus het dichtstbij dat je kan komen met een zwevendekommagetal is niet precies ⅓. Op een bepaald moment houdt het op omdat je computer niet genoeg geheugen heeft.
Afrondfouten kunnen zorgen voor onintuïtieve resultaten...
Dit is geen bug in Snap!, die rapporteert netjes het resultaat dat berekent wordt volgens de hardware voor een zwevendekommagetal.
Hoe goed de hardware ook is, bepaalde soorten berekeningen geven waarschijnlijk grove fouten met zwevendekommagetallen. Een simpel voorbeeld is twee getallen van elkaar aftrekken die heel dicht bij elkaar liggen. Het correcte antwoord ligt in dat geval in de buurt van nul en als de getallen dicht genoeg bij elkaar liggen zal door afrondfouten het resultaat van de berekening onderstromen. Dit betekent dat het gerapporteerde resultaat lager ligt dan het daadwerkelijke resultaat. Dus bij de aftreksom 2 - 2,0001 wordt dan 0 gerapporteerd in plaats van 0,0001.
Een beroemd voorbeeld is de Ariane-raket die gelanceerd werd op 4 Juni 1996. Tijdens de 37ste seconde van de vlucht, probeerde het systeem een 64-bit zwevendekommagetal om te zetten in een 16-bitgetal, maar in plaats daarvan werd er een overstroomfout gerapporteerd, wat werd geïnterpreteerd door het navigatiesysteem als vliegdata. Dit zorgde ervoor dat de raket van zijn koers ging en zichzelf verwoestte.
Het Patriot-raketafweersysteem dat gebruikt werd tijdens de Golfoorlog had ook last van een afrondfout (Skeel 1992, U.S. GAO 1992). Het systeem gebruikte een tijdmeter die werkte met hele getallen en optelde met intervallen van 0,1 secondes. Het probleem was dat de hele getallen werden omgezet in decimale getallen door zich te vermenigvuldigen met de binaire benadering van 0,1: 0,00011001100110011001100 2 = 209715/2097152.
Dit betekende dat na 100 uur (3,6 × 10 6 tellen), er een fout was van
(\frac{1}{10}-\frac{209715}{2097152})(3600\times100\times10)=\frac{5625}{16384} \approx 0,3433 \text{ seconds}
Dit verschil zorgde ervoor dat het systeem niet meer goed zijn doel kon vinden. Toen dus later een Irakese raket werd afgevuurd die niet werd gestopt door het systeem, kwamen er 28 mensen om het leven.
Overgenomen van Analoge en Digitale Conversie (Engels) , door Wikibooks bijdragers, https://en.wikibooks.org/wiki/Analog_and_Digital_Conversion/Fixed_Wordlength_Effects
Computerberekeningen met hele getallen zijn simpel: of je krijgt een correct, heel getal of als het resultaat niet past in een heel getal (dat geen bignum is) dan krijg je een overstroomfout en wordt het resultaat, als het goed is, omgezet in een zwevendekommagetal (zoals bij 30!).
Computerberekeningen met zwevendekommagetallen daarentegen zijn moeilijk om precies goed te krijgen. Voor 1985 had ieder computermodel een ander formaat zwevendekommagetal en allemaal gaven ze foute antwoorden op bepaalde vragen. Deze situatie werd opgelost door de IEEE 754 zwevendekommastandaard die nu door iedere computerfabrikant gebruikt wordt.
0001 1110 0011 0010
.
Dit voorkomt het 0,2+0,4-probleem, maar werkt niet voor breuken die in decimaal een oneindige
reeks cijfers nodig hebben zoals ⅓.
1111
, dan is 2,5e+4
gelijk aan: 0010 1110 0101 1111 0100
. (We hebben gezien in de vorige les dat e+
gelijk is aan "keer tien tot de macht")
Zonder bignums wordt een resultaat dat te groot is voor een heel getal, omgezet in een zwevendekommagetal.
Wat gebeurt er? Ook al is 200! vrij groot het is niet "oneindig". Het foute resultaat wordt veroorzaakt door de limiet van de grootte van zwevendekommagetallen. Als het resultaat van de berekening groter is dan kan worden opgeslagen dan rapporteert de computer een speciale code die de taal interpreteert als Oneindig of ∞.
Hoe weet een programmeertaal of het een bitreeks moet interpreteren als een heel getal, een zwevendekommagetal, een stuk tekst of iets anders? Programmeertalen doen dit op verschillende manieren, maar er is altijd een aantal extra bits die aangeven wat het data-type is van een bitreeks, die dus vertelt aan de computer hoe de bitreeks geïnterpreteerd moet worden.
onwaar
en 1 voor waar
. In goed ontworpen talen (zoals talen gebaseerd op Scheme) zit het data-type vast aan de waarde
zelf, dit zijn talen met dynamische waardes. In andere talen is het zo dat wanneer je een
variabele aanmaakt, je moet zeggen wat voor type
waarde de variabele zal bevatten. Dan zit het data-type dus vast aan de variabele, talen
met dit systeem zijn talen met statische waardes. Stel je wilt een variabele x
de waarde 5 geven, in een taal met dynamische waardes zou dat er zo uit kunnen zien:
x = 5;
In een taal met statische waardes ziet dat er zo uit:
Getal x;
x wordt aangemaakt als een Getal-variabele.
x = 5;
x krijgt de waarde 5.
Snap! heeft pluspunten die veel andere talen niet hebben en het is zeer waarschijnlijk dat je bij je volgende informaticacursus een taal met statische waardes zal leren gebruiken.