Lars Gjörling
<6825>
· Text 9595 · w8 · kommentar
1990-06-25 23:07
Ärende: Flyttalshantering
Det där med lagring av flyttal är kanske inte det allra enklaste
att skriva om på ett lättbegripligt sätt, men jag skall försöka.
I matematiken skriver man ofta tal som tiopotenser, t.ex.
800.32 skrivs då vanligen som 8.0032*10**2, dvs första faktorn
är ett tal mellan 1 och 10. Man kunde också välja att skriva
faktorn som ett tal mellan 0.1 och 1: 0.80032*10**3. Om vi inför
namnet mantissa (m) för faktorn och exponent (e) för tiopotensens
exponent: m*10**e där 0.1 < abs(m) < 1. (Jag använder här deci-
malpunkt och inte decimalkomma på amerikanskt sätt!).
Nu är det emellertid fråga om binära tal. Även hos binära tal kan
man använde 'decimalpunkt' (borde kanske kallas 'bimalpunkt' el.dyl).
Exempelvis talet 1101.101 betyder decimalt:
1*2**3 + 1*2**2 + 0*2**1 + 1*2**0 + 1*2**(-1) + 0*2**(-2) + 1*2**(-3)
=
= 8 + 4 + 0 + 1 + 0.5 + 0 + 0.125
=
= 13.625.
Det betyder att exempelvis det binära talet 0.1 motsvarar decimalt 0.5.
Det decimala talet 0.1 kan inte skrivas binärt annat än som ett oänd-
ligt 'decimaltal' (bimaltal): 0.0001100110011001100....... (kolla gärna
genom att dela upp det i summan av två konvergenta serier).
Man kan nu skriva ett binärt flyttal som m*2**e där 0.1 < abs(m)
< 1
(0.1 och 1 är här binära tal).
Skall man lagra detta flyttal i 4 bytes, så skriver man exponenten i
en
byte och mantissan i de tre följande bytarna. Låt oss kalla dem för
e-byten, m1-, m2- och m3-byten. Eftersom exponenten kan vara positiv
eller negativ, så ökar man den vid lagringen med 128. Värdet 128 i
e-byten betyder alltså e = 0, värdet 138 betyder e = 10 och e = 122
betyder e = -6.
(Jag är förvånad över att du i inlägget påstår att 800.32 har e-byten
132, på min PC blir den 138 som den bör vara. Kanske har ABC-datorn en
annan matematisk regel, jag kan inte prova just nu?).
För att få fram exponenten för talet 800.32, ser man efter, vilken
två-potens som man behöver dividera med för att få ett decimaltal
mellan 0.5 och 1 (obs att 0.5 decimalt motsvarar 0.1 binärt). Man
finner att det är 1024 (= 2*10) man måste dividera med, och alltså
är e = 10 och e-byten 138.
För att få m1, m2 och m3, kan du ta en räknedosa och utföra divisionen
800.32 / 1024 = 0.7815625.
Multiplicera detta med 256, så får du 200.08. Heltalsdelen av detta
ger m1 = 200.
Bråkdelen 0.08 multipliceras med 256 --> 20.48. Heltalsdelen av detta
ger m2 = 20.
Bråkdelen 0.48 multipliceras med 256 --> 122.88. Heltalsdelan av detta
ger m3 = 122, men eftersom vi inte skall fortsätta med m4 ... så avrundar
vi 122.48 till 123.
Men... säger du nu. m1 har ju värdet 72 och inte 200 på min dator. Med
detta förhåller det sig på följande sätt:
Den regel, som används vid bestämning av exponenten, gör att högsta biten
i m1 ALLTID måste bli en etta!!! Av denna anledning sätter man inte
ut
den, utan använder istället högsta biten i m1 för att visa tecknet hos
mantissan. Är mantissan positiv, sätter man högsta biten i m1 till 0
och är den negativ, sätter man den till 1. I det här fallet är mantissan
positiv, och därför sätter man högsta biten till 0. Drag bort 128 från
200, så får du 72. Detta tal 72 betyder att mantissan är ett positivt
tal
och att m1 egentligen har värdet 72 + 128 = 200.
Vill du gå motsatta vägen, så gör på följande sätt:
Öka m1 från 72 till 200 och dividera 200 med 256 --> 0.78125.
Lägg till m2/(256*256) --> 0.78125 + 20/65536 = 0.7815551758
Lägg till m3/(256*256*256) --> 0.7815625072
Multiplicera detta med 2**e (dvs 1024) --> 800.32
DET VAR VÄL ENKELT, ELLER HUR??