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, ,