Gå til indholdet

Talsystemer

Hvis du er begynder indenfor softwareudvikling, er det vigtigt at have en grundlæggende forståelse af talsystemer - i hvert fald de tre mest almindelige talsystemer: decimal, binær og hexadecimal. Du vil konsekvent støde på disse talsystemer, når du arbejder med software, og det er vigtigt at forstå, hvordan de fungerer og hvordan de konverteres mellem hinanden. Det vil hjælpe dig med at forstå, hvordan computere repræsenterer og behandler data, og hvordan du kan arbejde med tal i din kode.

Så selvom det virker som en tør og teknisk detalje, er det et vigtigt emne at have dækket, inden vi begynder at snakke om programmering.

Det decimale talsystem

Det decimaltalsystem er det talsystem, vi bruger i vores dagligdag. Det er baseret på ti cifre: 0, 1, 2, 3, 4, 5, 6, 7, 8 og 9. Hvert ciffer repræsenterer en potens af 10, hvor positionen af cifferet bestemmer værdien. For eksempel repræsenterer tallet 123 følgende potenser af 10:

  • Første position fra højre (3) er $3 \cdot 10^0$, som er 3.
  • Anden position (2) er $2 \cdot 10^1$, som er 20.
  • Tredje position (1) er $1 \cdot 10^2$, som er 100.

For at finde den decimal værdi, lægger vi disse potenser sammen: $100 + 20 + 3 = 123$. Dette er en simpel måde at forstå, hvordan decimaltalsystemet fungerer, og hvordan vi repræsenterer tal i vores dagligdag.

Skal man foretage simple beregninger - eksempelvis addition - er det er nemt at bruge det decimale talsystem:

  10
 + 8
 ---
  18

eller

   1  (menter)  
  123
 + 49
 ----
  172

Beregninger som disse kommer naturligvis ikke som nogen overraskelse, men det er vigtigt at forstå, at samme beregningsprincipper gælder for andre talsystemer.

Det binære talsystem

I det binære talsystem bruger vi kun to cifre, 0 og 1 og arbejder i potens af 2, i modsætning til det decimaltalsystem vi normalt anvender, som har ti cifre (0-9) og arbejder i potens af 10. Dette talsystem er fundamentet for al moderne computer teknologi, fordi det er ekstremt effektivt til elektronisk databehandling.

Hvorfor netop binært? Det handler om de mest grundlæggende elektroniske komponenter i en computer – transistorerne. En transistor i en computer kan have to tilstande: tændt eller slukket. Elektronisk svarer det groft sagt til, at der enten er lav spænding/ingen aktivt signal eller høj spænding/et aktivt signal. Derfor passer det binære talsystem godt til computere: 0 kan repræsentere slukket eller lav spænding, og 1 kan repræsentere tændt eller høj spænding.

Hver binær cifre kaldes en ‘bit’, som er en sammentrækning af “binary digit”. Bits er byggestenene i det binære talsystem. Når vi kombinerer bits, kan vi danne mere komplekse datastrukturer. For eksempel bruger vi 8 bits til at danne en ‘byte’, og med forskellige kombinationer af otte tændte eller slukkede bits kan vi repræsentere alt fra tal til bogstaver og andre symboler.

Mest kendte forkortelser inden for det binære talsystem

Her er nogle af de mest kendte forkortelser og enheder, du vil støde på, når du arbejder med binære systemer i softwareudvikling:

  • Bit (b): Den mindste enhed af data i computeren. En bit kan være enten 0 eller 1.
  • Nibble: En halv byte, bestående af 4 bits.
  • Byte (B): En samling af 8 bits. En byte kan repræsentere 256 forskellige værdier (fra 0 til 255).
  • Word: En samling af bits, typisk 16, 32 eller 64 bits afhængig af computerarkitekturen.
  • Kilobit (Kb): 1.000 bits (ikke at forveksle med kibibit, som er 1.024 bits).
  • Kilobyte (KB): 1.000 bytes (ikke at forveksle med kibibyte, som er 1.024 bytes).
  • Megabit (Mb): 1.000.000 bits (ikke at forveksle med mebibit, som er 1.048.576 bits).
  • Megabyte (MB): 1.000.000 bytes (ikke at forveksle med mebibyte, som er 1.048.576 bytes).
  • Gigabit (Gb): 1.000.000.000 bits (ikke at forveksle med gibibit, som er 1.073.741.824 bits).
  • Gigabyte (GB): 1.000.000.000 bytes (ikke at forveksle med gibibyte, som er 1.073.741.824 bytes).
  • Terabit (Tb): 1.000.000.000.000 bits (ikke at forveksle med tebibit, som er 1.099.511.627.776 bits).
  • Terabyte (TB): 1.000.000.000.000 bytes (ikke at forveksle med tebibyte, som er 1.099.511.627.776 bytes).

Disse enheder og forkortelser er grundlæggende for forståelsen af, hvordan data måles og håndteres i computere.

For at forstå hvordan vi regner i binært, kan vi tage et simpelt eksempel. Betragt følgende binære tal: 00001011. Dette tal læses fra højre mod venstre, hvor hver position repræsenterer en stigende potens af 2:

  • Første position fra højre (1) er $2^0$, som er $1$.
  • Anden position (1) er $2^1$, som er $2$.
  • Tredje position (0) er $2^2$, som er $4$.
  • Fjerde position (1) er $2^3$, som er $8$.
  • Femte position (0) er $2^4$, som er $16$.
  • Sjette position (0) er $2^5$, som er $32$.
  • Syvende position (0) er $2^6$, som er $64$.
  • Ottende position (0) er $2^7$, som er $128$.

For at finde den decimal værdi, lægger vi kun de værdier sammen, hvor der er en 1’er i det binære tal: $8 + 0 + 2 + 1 = 11$.

Så det binære tal 1011 svarer til det decimal tal 11:

| 128 | 64  | 32  | 16  | 8   | 4   | 2   | 1   |
| --- | --- | --- | --- | --- | --- | --- | --- |
| 0   | 0   | 0   | 0   | 1   | 0   | 1   | 1   |

= $0 + 0 + 0 + 0 + 8 + 2 + 1 = 11$

Det binære tal 10101010 svarer til det decimal tal 170:

| 128 | 64  | 32  | 16  | 8   | 4   | 2   | 1   |
| --- | --- | --- | --- | --- | --- | --- | --- |
| 1   | 0   | 1   | 0   | 1   | 0   | 1   | 0   |

= $128 + 0 + 32 + 0 + 8 + 0 + 2 + 0 = 170$

Dette system gør det muligt for computere at behandle og lagre en enorm mængde information meget effektivt og er grunden til, at binære talsystem er så fundamentalt i alt fra software programmering til databehandling og digital kommunikation.

Tip

Du kan eksperimentere med binære tal og konverteringer på https://mcronberg.github.io/csdemo/numbers.html. Prøv at konvertere mellem decimal og binær og se, hvordan tallene repræsenteres i de to talsystemer.

Skal man foretage simple beregninger - eksempelvis addition - fungerer det som i det decimale talsystem:

  00001010 (10)
  00000100 (8)
  --------
  00001110 (18)

eller

        1 (menter)
  00000001 (1)
  00000011 (3)
  --------
  00000100 (4)

Er det vigtigt for begyndere?

For de fleste begyndere i softwareudvikling er det ikke nødvendigt at have en dyb forståelse af det binære talsystem. Dog er det nyttigt at have en grundlæggende forståelse af, hvordan binære tal fungerer, da det er grundlaget for alt, hvad der sker i en computer. At forstå, hvordan data repræsenteres og behandles i binært, kan hjælpe dig med at forstå, hvordan computere fungerer og hvordan software fungerer på et grundlæggende niveau.

Kort om kvantecomputere

Klassiske computere arbejder med bits, som er 0 eller 1. Kvantecomputere arbejder med qubits, som følger kvantefysiske regler og derfor ikke bare er enten 0 eller 1 på samme enkle måde. Her spiller begreber som superposition og sammenfiltring ind, og det gør emnet meget mere komplekst end almindelig binær logik.

Hvis du har hørt om Niels Bohr, er det ikke tilfældigt: hans arbejde med kvantefysik var med til at lægge noget af det teoretiske fundament for den forståelse af atomer og kvantetilstande, som moderne kvantecomputing bygger videre på. Som begynder behøver du dog ikke forstå detaljerne - pointen er bare, at klassiske computere bruger bits, mens kvantecomputere bygger på en helt anden og langt mere avanceret fysisk model.

Kan du se hvad klokken er?

På diverse uddannelser er det normale ur over døren skiftet ud med et binært ur. Det er en sjov måde at lære at læse binære tal på. Her er et eksempel på hvordan et binært ur kan se ud:

Repræsentation af værdier i computere

Computere repræsenterer altså data i binær form ved hjælp af bits og bytes, og der er mange forskellige værdier du kunne ønske at gemme. Her er en grundlæggende gennemgang af, hvordan forskellige typer værdier repræsenteres:

Heltal

Heltal kan repræsenteres ved forskellige antal bytes:

  • 1 byte (8 bits): Kan repræsentere værdier fra 0 til 255 (uden fortegn) eller fra -128 til 127 (med fortegn).
  • 2 bytes (16 bits): Kan repræsentere værdier fra 0 til 65.535 (uden fortegn) eller fra -32.768 til 32.767 (med fortegn).
  • 4 bytes (32 bits): Kan repræsentere værdier fra 0 til 4.294.967.295 (uden fortegn) eller fra -2.147.483.648 til 2.147.483.647 (med fortegn).
  • 8 bytes (64 bits): Kan repræsentere værdier fra 0 til 18.446.744.073.709.551.615 (uden fortegn) eller fra -9.223.372.036.854.775.808 til 9.223.372.036.854.775.807 (med fortegn).

Det er værd at bemærke, at 64 bit er meget stort. Det er nok til at tælle ekstremt mange hændelser, gemme meget store id-numre og arbejde med tidsmålinger og datamængder i store systemer. I mange moderne programmeringssprog bruges 64-bit heltal derfor, når 32 bit ikke er nok.

Tip

Prøv at se https://mcronberg.github.io/csdemo/ram.html for at se hvordan simpel hukommelse i en computer er organiseret.

Negative tal

Negative tal repræsenteres typisk ved hjælp af den såkaldte to-komplement metode. For at repræsentere et negativt tal, inverteres (ændres) alle bits i tallet fra 0 til 1 og fra 1 til 0, og derefter lægges 1 til resultatet.

Eksempel: For et 4-bit system:

  • Tallet +3 repræsenteres som 0011.
  • For at finde repræsentationen af -3:
  • Inverter alle bits i 0011: 1100.
  • Læg 1 til resultatet: 1100 + 1 = 1101.

Så i et 4-bit system er +3 repræsenteret som 0011, og -3 er repræsenteret som 1101.

For at konvertere tilbage fra to-komplement til et negativt tal: - Hvis det første (venstre) bit er 1, er tallet negativt. - Inverter alle bits og læg 1 til resultatet.

Eksempel: For at konvertere 1101 tilbage til -3:

  • Inverter 1101: 0010.
  • Læg 1 til resultatet: 0010 + 1 = 0011.
  • Resultatet er -3.

Du behøver ikke at forstå detaljerne i to-komplement metoden - det er mere vigtigt at forstå, at computere bruger denne metode til at repræsentere negative tal.

Kommatal

Kommatal (decimaltal) repræsenteres ved hjælp af IEEE 754 standarden (også kaldet floating point), som deler tallet i tre dele: fortegn, eksponent og mantisse. De to mest almindelige repræsentationer er:

  • 32-bit (single precision): Bruger 1 bit til fortegn, 8 bits til eksponent, og 23 bits til mantisse.
  • 64-bit (double precision): Bruger 1 bit til fortegn, 11 bits til eksponent, og 52 bits til mantisse.

Således vil man i et 32-bit system kunne repræsentere tal som 3.14159 eller 1.2345678e-10, mens man i et 64-bit system kan repræsentere langt større og mere præcise tal.

Igen, det er ikke nødvigt at forstå detaljerne i IEEE 754 standard - det er vigtigere at forstå, at computere bruger denne metode til at repræsentere kommatal. Men der skal ikke meget fantasi til at forestille sig, at det kan være en udfordring at arbejde med kommatal i et binært system, og at der kan opstå afrundingsfejl hvis man ikke er opmærksom. Det kan resultere i fejl i beregninger, som kan have alvorlige konsekvenser i nogle situationer.

I videoen forklares det, hvordan en lille afrundingsfejl i Patriot missilsystemet under Golfkrigen i 1991 førte til, at systemet fejlede i at opspore og afværge en irakisk Scud-missil, hvilket resulterede i 28 døde og 260 sårede soldater. Fejlen opstod ved konvertering af tidspunkter til binære tal, hvilket resulterede i en positionsfejl på 573 meter.

Summering

Forståelsen af disse grundlæggende repræsentationer er vigtig for at kunne arbejde med data i programmering, da det giver indsigt i, hvordan computere gemmer og behandler information.

Info

Kan du se hvordan alt i en klassisk computer er baseret på binære tal? Det er fundamentet for alt, hvad der sker i en computer, og det er derfor vigtigt at have en grundlæggende forståelse af, hvordan binære tal fungerer.

Du behøver ikke forstå 2-komplement metoden, IEEE 754 standard eller Unicode-tegnsæt - det er mere vigtigt at forstå, at computere bruger disse metoder til at repræsentere data, og at det er grundlaget for alt, hvad der sker i en computer.

Det hexadecimale talsystem

Det hexadecimale talsystem er et positionssystem med basis 16, hvilket betyder, at det bruger 16 forskellige cifre. Disse er de velkendte cifre fra 0 til 9 suppleret med bogstaverne A til F, hvor A repræsenterer 10, B er 11, C er 12, D er 13, E er 14, og F er 15 i det decimale system.

For at forstå hvordan man arbejder med hexadecimale tal, kan vi tage et simpelt eksempel. Betragt følgende hexadecimale tal: 11. Dette tal læses fra højre mod venstre, hvor hver position repræsenterer en stigende potens af 16:

  • Første position fra højre (1) er $1 \cdot 16^0$, som er $1$.
  • Anden position (1) er $1 \cdot 16^1$, som er $16$.

For at finde den decimale værdi, lægger vi værdierne sammen: $1 + 16 = 17$.

Eller hvad med tallet 2E?

  • Første position fra højre (E) er $14 \cdot 16^0$, som er $14$.
  • Anden position (2) er $2 \cdot 16^1$, som er $32$.

For at finde den decimale værdi, lægger vi værdierne sammen: $32 + 14 = 46$.

Hvad så med tallet FF?

  • Første position fra højre (F) er $15 \cdot 16^0$, som er $15$.
  • Anden position (F) er $15 \cdot 16^1$, som er $240$.

For at finde den decimale værdi, lægger vi værdierne sammen: $240 + 15 = 255$.

Slutteligt - hvad med tallet ABCD?

  • Første position fra højre (D) er $13 \cdot 16^0$, som er $13$.
  • Anden position (C) er $12 \cdot 16^1$, som er $192$.
  • Tredje position (B) er $11 \cdot 16^2$, som er $2816$.
  • Fjerde position (A) er $10 \cdot 16^3$, som er $40960$.

For at finde den decimale værdi, lægger vi værdierne sammen: $40960 + 2816 + 192 + 13 = 43981$.

Kan du se hvad klokken er?

Næste skridt

Når du har den grundlæggende idé om binær, decimal og hexadecimal på plads, er næste naturlige skridt at se på, hvordan en computer faktisk bruger disse repræsentationer i elektronik, hukommelse og CPU. Fortsæt derfor med Hardware.

Tidligere nævnte jeg, at det klassike ur over døren i undervisningslokalerne var skiftet ud med et binært ur. Der findes også hexadecimale ure, og her er et eksempel på hvordan et hexadecimal ur kan se ud:

Det hexadecimale system bruges ofte i programmering og informationsteknologi, fordi det er mere kompakt end det binære system, men stadig kan mappes direkte til det, hvilket gør det enklere at læse og skrive binære data. Hver hexadecimal ciffer kan præcist repræsentere fire binære cifre (bits), hvilket gør oversættelsen mellem de to systemer meget effektiv. For eksempel svarer et enkelt hexadecimal ciffer ‘F’ direkte til de binære cifre ‘1111’, og hexadecimal ‘2’ svarer til ‘0010’.

Denne direkte korrespondance gør det muligt at reducere kompleksiteten og længden af binære tal, hvilket er særligt nyttigt i felter som digital elektronik og computerprogrammering, hvor man ofte skal håndtere lange sekvenser af bits. At arbejde med hexadecimale tal reducerer risikoen for fejl, da det er lettere at skrive og kontrollere færre cifre.

For at konvertere fra binær til hexadecimal, grupperer man de binære cifre i grupper af fire fra højre mod venstre, og omdanner hver gruppe til det tilsvarende hexadecimale tal. Omvendt kan man let omdanne et hexadecimalt tal til binær ved at erstatte hvert hexadecimale ciffer med den tilsvarende gruppe af fire binære cifre.

Her er et par eksempler:

  • 0011 svarer til 3 i decimal og 3 i hexadecimal.
  • 1001 svarer til 9 i decimal og 9 i hexadecimal.
  • 1010 svarer til 10 i decimal og A i hexadecimal.
  • 1011 svarer til 11 i decimal og B i hexadecimal.

Ved større binære værdier kan det være nyttigt at opdele dem i grupper af fire for at lette konverteringen til hexadecimal.

For eksempel vil det binære tal 1101110110₂ konverteres til hexadecimal således:

  1. Opdel det binære tal i grupper af fire fra højre: 1101 1101 10
  2. Tilføj eventuelt foranstillede nuller for at fuldføre den sidste gruppe: 0011 0111 0110
  3. Omdan hver gruppe til det tilsvarende hexadecimale tal: 3 7 6

Derfor er 1101110110 binært lig med 376 i hexadecimalt. Denne teknik anvendes bredt i programmering, især til adressering af hukommelse og ved farvekodning i digitale medier, hvor hexadecimal kode er standard.

Det oktale talsystem

Udover det decimale, binære og hexadecimale talsystem, findes også det oktale talsystem, som er baseret på otte cifre (0-7). Dette talsystem bruges sjældent i moderne computere. Det oktale talsystem er dog stadig relevant i nogle sammenhænge, især i gamle systemer og i nogle former for digital kommunikation.

Bogstaver

Nu hvor vi har været omkring både binære og hexadecimale tal, er det lettere at se, hvordan computere gemmer tekst. Bogstaver og andre tegn repræsenteres ved hjælp af tegnsæt som ASCII eller Unicode:

  • ASCII: Bruger 7 bits til at repræsentere 128 forskellige tegn. For eksempel er ‘A’ repræsenteret som 65.
  • Unicode: Bruger flere bytes til at repræsentere et stort antal tegn fra forskellige skriftsystemer.

For eksempel repræsenterer Unicode-tegnet ‘A’ stadig 65, mens det japanske tegn ‘あ’ er repræsenteret som U+3042.

Her er en lille ASCII-tabel med nogle af de tegn, man oftest støder på:

Tegn Decimal Hex Binær
mellemrum 32 20 00100000
! 33 21 00100001
, 44 2C 00101100
0 48 30 00110000
1 49 31 00110001
9 57 39 00111001
A 65 41 01000001
B 66 42 01000010
C 67 43 01000011
D 68 44 01000100
K 75 4B 01001011
S 83 53 01010011
Z 90 5A 01011010
a 97 61 01100001
z 122 7A 01111010

Det vigtige mønster er, at hvert tegn i teksten gemmes som et tal. Det tal kan vises i decimal, hexadecimal eller binær form, men det er stadig det samme tegn.

Så når du skriver et Word dokument, sender en e-mail eller besøger en hjemmeside, bruger computeren disse tegnsæt til at vise bogstaver, tal og symboler på skærmen. Men alt er stadig baseret på binære tal, som computeren kan forstå og behandle. Så den binære repræsentation af “Hello, World!” kan se sådan ud:

01001000 01100101 01101100 01101100 01101111 00101100 00100000 01010111 01101111 01110010 01101100 01100100 00100001

fordi hvert bogstav er repræsenteret ved hjælp af en binær værdi.

H = 01001000
e = 01100101
l = 01101100
l = 01101100
o = 01101111
osv...

Et dansk eksempel er DASK, som stod for Dansk Aritmetisk Sekvens Kalkulator. Hvis vi konverterer “DASK” til tal, ser det sådan ud:

Tegn Decimal Hex Binær
D 68 44 01000100
A 65 41 01000001
S 83 53 01010011
K 75 4B 01001011

Hele ordet kan derfor skrives sådan:

  • Decimal: 68 65 83 75
  • Hex: 44 41 53 4B
  • Binær: 01000100 01000001 01010011 01001011

Hvis du går fra hex til binær, kan du tage ét hex-ciffer ad gangen, fordi hvert hex-ciffer svarer til 4 bits:

  • 4 = 0100
  • 4 = 0100
  • 4B = 0100 1011
  • 53 = 0101 0011

Derfor bliver 44 41 53 4B til 01000100 01000001 01010011 01001011.

Hvorfor kan man købe en t-shirt med 2A på?

Tidligere så vi, hvordan “Hello, World!” kunne repræsenteres i binære tal. Hvad med den hexadecimale repræsentation af “Hello, World!” - kunne der være en årsag til at man kan købe en t-shirt med “48 65 6C 6C 6F 2C 20 57 6F 72 6C 64 21” på brystet?

48x = 01001000b = H
65x = 01100101b = e
6Cx = 01101100b = l
osv...

Måske har du læst “Hitchhiker’s Guide to the Galaxy” af Douglas Adams, hvor svaret på alt er 42. I ASCII er 42 repræsenteret som ‘*’, så måske er svaret på alt et stjernetegn - der som bekendt i mange operativsystemer repræsenterer “alt”? Kan det forklare en t-shirt med “42” i binær form (00101010) eller hexadecimale form (2A)? Er 2A virkelig svaret på alt? 😄