Zahlendarstellung

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, $+\infty$, $-\infty$



AnyWare@Wachtler.de