Programmeren in C/Datatypes: verschil tussen versies

Verwijderde inhoud Toegevoegde inhoud
Nijdam (overleg | bijdragen)
Nijdam (overleg | bijdragen)
Regel 92:
== ''float'', ''double'' en ''long double'' ==
De typen ''float'', ''double'' en ''long double'' worden gebruikt om getallen met een drijvende komma op te slaan. Hoe de representatie van deze getallen plaatsvindt, is niet gespecificeerd en daarmee afhankelijk van de compiler. Het enige dat wel gespecificeerd is, is dat een ''double'' een grotere precisie en bereik heeft dan een ''float'' en een ''long double'' een grotere precisie en bereik heeft dan een ''double''. Over het algemeen kan gezegd worden dat deze drie de volgende standaard elementen hebben. Het loont de moeite om, als men programma's met ''floating-point''-getallen schrijft, te informeren naar de implementatie die de compiler gebruikt (ofwel: "''[[:w:RTFM|RTFM]]''").
 
Een getal wordt dan weergegeven als
 
:<math> x = sr^{e} *s\cdot m \cdot r^e.</math>
 
Daarin zijn:
 
{| class="prettytable"
Regel 100 ⟶ 106:
| radix || r || de wortel, het grondgetal
|-
| exponent || e || Dede exponent van de wortel
|-
| mantissa || m || een niet-negatief getal dat de waarde weergeeft.
|}
 
Verder is een bijzondere waarde gedefinieerd die bekend staat als ''NaN'' (''Not a Number''). Dit getalsymbool wordt gebruikt als een berekening geen numeriek resultaat heeft, (bijvoorbeeldzoals b "268/0"). ''NaN'' kent twee verschillende smaken:
Een getal wordt dan weergegeven als
 
<math> x = sr^{e} * m </math>
 
Verder is een bijzondere waarde gedefinieerd die bekend staat als ''NaN'' (''Not a Number''). Dit getal wordt gebruikt als een berekening geen numeriek resultaat heeft (bijvoorbeeld "268/0"). ''NaN'' kent twee verschillende smaken:
 
* ''Quiet NaN'', De expressie resulteert in een ''NaN'', maar verder gebeurt er niets.
* ''Signalling NaN'', Zodra deze variant voorkomt wordt een ''uitzondering'' gegenereerd (''an exception is raised''). Dit heeft in de regel een voortijdig afbreken van het programma tot gevolg.
 
Het is belangrijk te begrijpen dat een ''floating point''-getal niet hetzelfde is als het wiskundige concept ''Reëelreëel Getalgetal'' (element van <math>\mathbb{R}</math>). De laatstereële isgetallen continuevormen een continuüm, datwat wil zeggen dat voor elkelke reëeltwee getalreële getalgetallen a en b, met (a < b), een getal x bestaat zodat geldt:
 
:<math> a < x < b </math>
 
Floating point representatiesgetallen missen deze eigenschap, en vormen slechts een eindig deel van de reële getallen. Dit heeft tot gevolg dat een floating point variable '''niet''' elke denkbare waarde kan hebben en daarom '''niet''' altijd exact de weergave is van de waarde van de variabele. Vooral onder beginners leidt dit vaak tot problemen. Bijvoorbeeld...Bijvoorbeeld…
<math> a < x < b </math>
 
Floating point representaties missen deze eigenschap. Dit heeft tot gevolg dat een floating point variable '''niet''' elke denkbare waarde kan hebben en '''niet''' exact is. Vooral onder beginners leidt dit vaak tot problemen. Bijvoorbeeld...
{{code
|Taal= C
Regel 144 ⟶ 147:
</source>
}}
Bovenstaande code zal niet het resultaat opleveren dat de naïeve programmeur ervan verwacht, ondanks het feit dat 3*(1/3) wel degelijk 1 is. Dit ligt aan het feit dat een binaire representatie van 1/3 als floating point onmogelijk is en er dus een fout wordt geintroduceerdgeïntroduceerd. Een heleheel kleine fout weliswaar, (afhankelijk van de precisie van ''double'' op het platform in kwestie, maar genoeg om de ''is gelijk''-operator te ondermijnen. Over het algemeen kan men stellen dat het gebruik van de ''=='' (is-gelijk) operator met twee floating-point getallen uit den boze is.
 
De gebruikelijke oplossing ziet er (ongeveer) als volgt uit.
Regel 176 ⟶ 179:
</source>
}}
En "''Hey, Presto!''". De code werkt zoals het de bedoeling is omdat we nu rekening houden met de inherente fout die het gebruik van floating-point getallen oplevert. Met behulp van "''fabs(x*3 - 1.0) < EPSILON''" wordt het absolute verschil uitgerekend en als dit kleiner is dan een voorgedefinieerd maximum ('''EPSILON''') zijn de twee waarden "gelijk" of in ieder geval "gelijknagenoeg genoeggelijk". In de wandeling staat deze techniek ook wel bekend als "''close-enough comparison''". Een goede waarde voor EPSILON hangt af van de toepassing en de implementatie van de compiler (dus "''[[:w:RTFM|RTFM]]''", nogmaals).
 
==Vormen van getallen==
Informatie afkomstig van https://nl.wikibooks.org Wikibooks NL.
Wikibooks NL is onderdeel van de wikimediafoundation.