Taschenrechner
rechnen tatsächlich mit einer merkwürdigen Kreuzung aus Zweier- und
Zehnersystem, der sogenannten BCD-Arithmetik (BCD = binary coded decimal).
Dabei wird nicht die gesamte Zahl ins Zweiersystem übertragen, wie bei
anderen Rechnern, sondern jede Ziffer des Zehnersystems einzeln als kurze
Zahl im Zweiersystem.
Stack: Postscript, UPN
Speicher: konstant, variabel
CDC Cyber 76: CPU 1:30h, real 1-2 Tage bzw. Wochenende
Cyber 990: 20-30 min
Atari ST/FPU: 7h
AMD K7/600: 0.5sec
negative Zahlen:
a) ein Bit für Vorzeichen; der Rest ergibt den Betrag
b) Einerkomplementdarstellung
-|x| <= ( 2^n - 1 ) - |x|
01111111 = 127
...
00000001 = 1
00000000 = 0
11111111 = -0
11111110 = -1
...
10000000 = -127
Negieren: Bits invertieren
c) Zweierkomplement:
-|x| <= ( 2^n ) - |x|
01111111 = 127
...
00000001 = 1
00000000 = 0
11111111 = -1
11111110 = -2
...
10000000 = -128
Negieren: Bits invertieren
d) Excess/BIAS
11111111 = 127
...
10000000 = 0
01111111 = -1
...
00000000 = -128
Der folgende Text ist aus einem Programmkommentar entnommen, und nur
für mich als Merkhilfe gedacht:
// Dabei sollten sowohl Systeme mit einer internen Darstellung
// als "big endian" (Sun, Motorola 68xxx, PowerPC) als auch Systeme
// mit "little endian" (Intel) funktionieren.
// DEC Vax: gemischt:
Die Zahl 0x12345678
Big endian: Little endian: Vax (evtl.):
hohe Adressen...
0x12 0x78 0x56
0x34 0x56 0x78
0x56 0x34 0x12
0x78 0x12 0x34
niedrige Adressen...
Festkommazahlen:
feste Anzahl Vor- und Nachkommastellen
problematisch bei kleinen und großen Zahlen
Gleitkommazahlen: großer Bereich bei fester relativer Genauigkeit
rationale Zahlen
IEEE 754: Literatur
big/little endian byte order für double-Werte herausfinden,
dabei nebenbei prüfen, ob die Bitmuster IEEE 754 entsprechen.
Das funktioniert prinzipiell ähnlich wie bei den int-Werten:
in einer union liegen eine Gleitkommazahl (8 Byte) und ein char[]-
Feld parallel.
Wenn man jetzt bestimmte Werte in die Gleitkommazahl schreibt,
kann man im char[]-Feld die Werte der einzelnen Bytes angucken.
Byte <---3--><---2--><---1--><---0-->
Bit 3322222222221111111111
10987654321098765432109876543210
seeeeeeeemmmmmmmmmmmmmmmmmmmmmmm
BIAS für e:
Aufbau einer double nach IEEE ([3], [4]):
Byte <---7--><---6--><---5--><---4--><---3--><---2--><---1--><---0-->
Bit 666655555555554444444444333333333322222222221111111111
3210987654321098765432109876543210987654321098765432109876543210
seeeeeeeeeeemmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
Bit 63 (s) ist das Vorzeichen (0 ist '+', 1 ist '-')
Die 11 Bits 52-62 (e) stellen den Exponenten dar, verschoben um
den Wert 1023 ins Positive.
Die 52 Bits 0-51 (m) sind die Mantisse.
Bei normalisierten Zahlen (Wert für den Exponenten von -1022 bis 1023,
verschoben in den Bereich 1-2046 für e) wird vor der Binärziffernfolge
von m eine "1." gedacht, und nicht mit abgespeichert.
Beispiel 1:
Die Dezimalzahl 1.0 ist binär ebenfalls 1.0, also 1.0*2^0.
Die "1." wird nicht gespeichert, die gesamte Mantisse m ist 0.
Der Exponent ist 0, und wird um 1023(dez)=1111111111(binär)
verschoben.
s ergibt:
Byte <---7--><---6--><---5--><---4--><---3--><---2--><---1--><---0-->
Bit 666655555555554444444444333333333322222222221111111111
3210987654321098765432109876543210987654321098765432109876543210
seeeeeeeeeeemmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
bin: 0011111111110000000000000000000000000000000000000000000000000000
hex: 3 f f 0 0 0 0 0 0 0 0 0 0 0 0 0
Beispiel 2:
Die Dezimalzahl 1.03125 (1+2^-5) ist binär 1.00001, also 1.00001*2^0.
Die "1." wird nicht gespeichert, die gesamte Mantisse ist 0000100...
Der Exponent ist 0, und wird um 1023(dez)=1111111111(binär)
verschoben.
Das ergibt:
Byte <---7--><---6--><---5--><---4--><---3--><---2--><---1--><---0-->
Bit 666655555555554444444444333333333322222222221111111111
3210987654321098765432109876543210987654321098765432109876543210
seeeeeeeeeeemmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
bin: 0011111111110000100000000000000000000000000000000000000000000000
hex: 3 f f 0 8 0 0 0 0 0 0 0 0 0 0 0
Beispiel 3:
Die Dezimalzahl
1+(2^(-5))+(2^(-14))+(2^(-23))+(2^(-32))+(2^(-41))+(2^(-50))
ist binär
1.0000100000000100000000100000000100000000100000000100,
also 1.0000100000000100000000100000000100000000100000000100*2^0.
Die "1." wird nicht gespeichert, die gesamte Mantisse ist 0000100...
Der Exponent ist 0, und wird um 1023(dez)=1111111111(binär)
verschoben.
Das ergibt:
Byte <---7--><---6--><---5--><---4--><---3--><---2--><---1--><---0-->
Bit 666655555555554444444444333333333322222222221111111111
3210987654321098765432109876543210987654321098765432109876543210
seeeeeeeeeeemmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
bin: 0011111111110000100000000100000000100000000100000000100000000100
hex: 3 f f 0 8 0 4 0 2 0 1 0 0 8 0 4
denormalisierte Zahlen, NAN,
,