hvad er det mindste mulige antal? – Programmering ord af dagen

Marin ben
Marin ben Kristiansand

Følg

Aug 7, 2018 * 5 min læst

hvad er det mindste tal større end 0? Dette er et af de enkle spørgsmål med komplicerede svar et sted mellem “der er ingen” og “det afhænger”.

hvis du spørger en matematiker, vil de fortælle dig, at der ikke kan være et sådant tal, fordi det ville bryde matematik. Hvis du har et tal n, hvor n er det mindste tal efter 0, kan der ikke være et tal n/2, fordi n allerede er det mindste. Det betyder, at divisionen selv bryder sammen, hvilket matematikere ikke kan lide.

hvis du spørger en computer, får du faktisk et svar. I modsætning til den virkelige verden har computere ikke en uendelig mængde tal, fordi de simpelthen ikke kunne passe. Computere gemmer numre i hukommelsesregistre, og hvert register har et fast antal bits. Forestil dig, hvis du kun havde tre cifre. Det største antal du kunne repræsentere ville være 999. Dette er hvad der sker i en computer.

dette betyder, at sæt af heltal i en computer er begrænset af antallet af cifre. I en computer er der bestemt et største antal (for eksempel INT_MAX i C). Det er tallet med det maksimale antal cifre, som alle er indstillet til en binær 1. På et 8-bit system ville dette tal være 11111111.

vi kan komplicere tingene endnu mere ved at inkludere negative tal. Hvis vi har 8 bits data, kan vi bruge den første bit til at repræsentere tegnet på nummeret. 0 for plus og 1 for minus. Nu har vi 7 bits til vores cifre, så det største antal er 011111111, hvilket er mindre end vores tidligere største antal.

vi er stadig ikke færdige. Vi skal også repræsentere decimaltal. Selvom 0,12 er et lille tal, har det stadig tre cifre, ligesom 123. Forskellen er, at der er en ting mere, vi skal tænke på: decimalpunktet, også kaldet radispunktet. Vi er nødt til at gemme både cifrene og placeringen af radispunktet.

mens heltal er begrænset i, hvor store de kan være, er decimaltal begrænset i både størrelse og præcision. Hvis du har et fast antal cifre, er der kun så mange cifre, du kan sætte efter decimaltegnet. Derfor skal computere runde decimaltal.

Hvordan gemmer vi så disse decimaltal? Computere forstår kun heltal, så vi har brug for en måde at gemme et decimaltal kun ved hjælp af heltal.

sig, at vi har nummeret 3.14. Lad os starte med at skrive vores alle cifrene i nummeret. Vi får 314. Det er en begyndelse. Vi ved, at ved at multiplicere med kræfter på 10, kan vi “flytte” decimaltegnet omkring tallet. 314 * 10^-1 er 31,4, mens 314 * 10^-2 er 3,14.

alt, hvad vi behøver for at repræsentere tallet 3.14, er tre heltal: 314, 10 og -2. 314 er det, der kaldes en significand, og dette er alle cifrene i nummeret skrevet ud.

10 kaldes en Radik eller en base. Vi ved, at ved at multiplicere med kræfter på 10 kan vi flytte decimalpunktet omkring tal i base 10. Det samme fungerer for alle nummerbaser: i base 2 (eller binær) kan du flytte prikken ved at multiplicere med kræfter på 2.

den kraft, vi skifter med, kaldes eksponenten, og den fortæller os, hvor decimalpunktet er.

du kan skrive hvert decimaltal som disse tre tal med en simpel formel:

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

en computer gemmer et decimaltal ved at gemme tegnet, eksponenten og signifikanten i en enkelt streng på 32 eller 64 bitcifre. Normalt er der 1 bit for tegnet, 11 bits til at gemme eksponenten og 53 bits til at gemme significand, tilføje op til 64.

med det i tankerne, lad os komme tilbage til vores spørgsmål: Hvad er det mindste ikke-nul tal? Hvis vi kun har tre cifre til overs, er det mindste mulige tal 0, 01. Med fire cifre er det 0,001. Du vil bemærke et mønster her: betydningen er altid den samme, kun eksponenten ændres.

hvad vi har brug for er en signifikand af 1, fordi det er den mindste efter 0. Vi skal derefter flytte decimaltegnet så langt vi kan til venstre. For at gøre dette har vi brug for den mindste (mest negative) mulige eksponent.

hvor lille afhænger af layoutet af nummeret i hukommelsen. Hvis vi har 11 bit til eksponenten, kan vi kun skrive et tal, der er 10 bit langt, med 1 bit reserveret til tegnet. I et 64-bit system er den mindste eksponent -308.

i sidste ende ville det mindste mulige tal i et 64-bit system være omkring 1 * 10^-308. Det er lille!

vi fastslog, at der er et mindste antal. Dette tal fortæller os, hvor meget vi kan stole på vores computer. Hvis du laver noget, der kræver meget store tal eller meget præcise tal, skal du huske dette nummer.

det, vi lige har beregnet, er noget, der hedder enheden i sidste sted, eller ulp, af 0. Bortset fra at være et rigtig sejt ord, fortæller ulp os, hvad der er den mindste afstand mellem to tal i en computer. Vi beregnede ulp på 0, som er den mindste afstand mellem 0 og det næste tal.

hvis du tilføjer den beregnede værdi til 0 og forsøger at sammenligne dem, ville de ikke være det samme tal. Men hvis du tilføjer en værdi, der er mindre end ulp, ville det stadig være det samme antal for så vidt angår computeren.

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

for os er det indlysende, at tilføjelse af en ikke-nul værdi til et tal vil producere et andet tal, men en computer skal runde et sted, så det kan ikke nødvendigvis fortælle, om to tal er ens.

for at sammenligne computersystemer lettere bruger vi ulp på 1 og kalder det maskinen epsilon. Når du kender maskinen epsilon, kan du beregne enhver anden ulp med følgende formel:

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

den værdi, vi har beregnet, er meget lille, så du rammer sandsynligvis ikke den grænse, mens du koder. Men, vi beregnet værdien for 0. Med flere cifre, der er nødvendige for venstre side af decimaltegnet, jo færre har vi til højre side. Det betyder, at jo større tallet er, desto mindre præcision har du. Med andre ord er ulp en direkte funktion af eksponenten. Når du skifter decimaltegnet til højre, øges ulp ‘ en, og du mister præcision.

jeg håber, at disse oplysninger vil hjælpe dig næste gang du får en underlig floating point-fejl i din kode. Husk, computere er ret magtfulde, men selv en computer har sine grænser.



+