Wat is het kleinst mogelijke getal? – Programmeren Woord van de dag

Marin Benčević
Marin Benčević

volgen

7 Aug. 2018 * 5 min. lezen

Wat is het kleinste getal groter dan 0? Dit is een van die eenvoudige vragen met ingewikkelde antwoorden ergens tussen “Er is geen” en”het hangt ervan af”.

als je het aan een wiskundige vraagt, zullen ze je vertellen dat er niet zo ‘ n getal kan zijn omdat het wiskunde zou breken. Als je een getal n hebt, waarbij n het kleinste getal is na 0, dan kan er geen getal n/2 zijn, omdat n al het kleinste is. Dit betekent dat de deling zelf afbreekt, wat wiskundigen niet leuk vinden.

als u een computer vraagt, krijgt u een antwoord. In tegenstelling tot de echte wereld hebben computers geen oneindig aantal getallen omdat ze gewoon niet passen. Computers slaan nummers op in geheugenregisters en elk register heeft een vast aantal bits. Stel je voor dat je maar drie cijfers had. Het grootste getal dat je zou kunnen vertegenwoordigen zou 999 zijn. Dit gebeurt er in een computer.

dit betekent dat de verzameling gehele getallen in een computer wordt beperkt door het aantal cijfers. In een computer is er zeker een grootste getal (bijvoorbeeld INT_MAX in C). Het is het getal met het maximum aantal cijfers, die allemaal zijn ingesteld op een binair 1. Op een 8-bits systeem zou dit getal 11111111zijn.

we kunnen de zaken nog ingewikkelder maken door negatieve getallen op te nemen. Als we 8 bits gegevens hebben, kunnen we het eerste bit gebruiken om het teken van het getal weer te geven. 0 voor plus en 1 voor minus. Nu hebben we 7 bits voor onze cijfers, dus het grootste getal is 011111111 wat kleiner is dan ons vorige grootste getal.

We zijn nog steeds niet klaar. We moeten ook decimale getallen vertegenwoordigen. Zelfs als 0.12 een klein getal is, heeft het nog steeds drie cijfers, net als 123. Het verschil is dat er nog één ding is waar we aan moeten denken: de decimale punt, ook wel het radixpunt genoemd. We moeten zowel de cijfers als de positie van het radixpunt opslaan.

terwijl gehele getallen beperkt zijn in hoe groot ze kunnen zijn, zijn decimale getallen beperkt in zowel grootte als precisie. Als je een vast aantal cijfers hebt, kun je maar zoveel cijfers achter de decimale punt zetten. Daarom moeten computers decimale getallen afronden.

hoe slaan we deze decimale getallen dan op? Computers begrijpen alleen gehele getallen, dus we hebben een manier nodig om een decimaal getal alleen op te slaan met behulp van gehele getallen.

zeggen dat we het getal 3.14hebben. Laten we beginnen met het schrijven van onze alle cijfers van het nummer. We krijgen 314. Dat is een begin. We weten dat door te vermenigvuldigen met bevoegdheden van 10, We kunnen “verplaatsen” de komma rond het getal. 314 * 10^-1 is 31,4, terwijl 314 * 10^-2 3,14 is.

alles wat we nodig hebben om het getal 3.14 weer te geven is drie gehele getallen: 314, 10 en -2. 314 is wat men een significand noemt, en dit zijn alle cijfers van het getal uitgeschreven.

10 wordt een radix of een base genoemd. We weten dat door te vermenigvuldigen met machten van 10 we de decimale punt rond getallen in basis 10 kunnen verplaatsen. Hetzelfde werkt voor alle nummerbases: in BASIS 2 (of binair), kunt u de punt verschuiven door te vermenigvuldigen met bevoegdheden van 2.

de macht waarmee we verschuiven wordt de exponent genoemd, en het vertelt ons waar de decimale punt is.

u kunt elk decimaal getal schrijven als deze drie getallen met een eenvoudige formule:

number = significand * base^exponent3.14 = 314 * 10^-2
32.8 = 328 * 10^-1

een computer slaat een decimaal getal op door het teken, de exponent en de significand in een enkele reeks van 32 of 64 bits cijfers op te slaan. Meestal is er 1 bit voor het teken, 11 bits om de exponent op te slaan en 53 bits om de significand op te slaan, opgeteld tot 64.

met dat in gedachten, laten we terugkeren naar onze vraag: Wat is het kleinste niet-nulgetal? Als we maar drie cijfers over hebben, is het kleinst mogelijke getal 0,01. Met vier cijfers is het 0,001. Je ziet hier een patroon: de significand is altijd hetzelfde, alleen de exponent verandert.

wat we nodig hebben is een significand van 1, want dat is de kleinste na 0. We moeten dan de komma zo ver mogelijk naar links verschuiven. Om dit te doen hebben we de kleinst mogelijke (meest negatieve) exponent nodig.

hoe klein, hangt af van de opmaak van het getal in het geheugen. Als we 11 bits voor de exponent hebben, kunnen we alleen een getal opschrijven dat 10 bits lang is, met 1 bit gereserveerd voor het teken. In een 64-bits systeem is de kleinste exponent -308.

uiteindelijk zou het kleinst mogelijke getal in een 64-bits systeem rond 1 * 10^-308liggen. Dat is klein!

we hebben vastgesteld dat er een kleinste getal is. Dit nummer vertelt ons hoeveel we onze computer kunnen vertrouwen. Als je iets doet dat zeer grote getallen of zeer precieze getallen vereist, moet je dit getal in gedachten houden.

wat we zojuist hebben berekend is iets dat de eenheid in de laatste plaats, of ulp, van 0 wordt genoemd. Behalve dat het een echt cool woord is, vertelt ulp ons wat de minimale afstand is tussen twee getallen in een computer. We berekenden de ulp van 0, wat de minimale afstand is tussen 0 en het volgende getal.

als u de berekende waarde toevoegt aan 0 en ze probeert te vergelijken, zouden ze niet hetzelfde getal zijn. Als u echter een waarde toevoegt die kleiner is dan de ulp, zou het nog steeds hetzelfde getal zijn voor zover het de computer betreft.

print(0 == 0 + ulp(0)) // false
print(0 == 0 + ulp(0) / 2) // true

voor ons is het duidelijk dat het toevoegen van een niet-nul waarde aan een getal een ander getal zal produceren, maar een computer moet ergens rond, dus het kan niet noodzakelijkerwijs vertellen of twee getallen hetzelfde zijn.

om computersystemen gemakkelijker te vergelijken, gebruiken we de ulp van 1, en noemen het de machine epsilon. Zodra u de machine epsilon kent, kunt u elke andere ulp berekenen met de volgende formule:

ulp(x) = machine epsilon * radix^exponent(x)

de waarde die we hebben berekend is erg klein, dus je zult waarschijnlijk niet die limiet raken tijdens het coderen. Maar we hebben de waarde voor 0 berekend. Met meer cijfers nodig voor de linkerkant van de decimale punt, hoe minder we hebben voor de rechterkant. Dit betekent dat hoe groter het aantal, hoe minder precisie je hebt. Met andere woorden, de ulp is een directe functie van de exponent. Als je de decimale punt naar rechts verschuift, neemt de ulp toe en verlies je precisie.

ik hoop dat deze informatie u zal helpen de volgende keer dat u een rare floating point fout in uw code. Vergeet niet, computers zijn vrij krachtig, maar zelfs een computer heeft zijn grenzen.



+