float nach binary...
-
BlackJack
@jens: Da scheint es ein Muster zu geben, dass sich der Wert immer bei einer 2er-Potenz ändert. 
- jens
- Python-Forum Veteran
- Beiträge: 8502
- Registriert: Dienstag 10. August 2004, 09:40
- Wohnort: duisburg
- Kontaktdaten:
Stimmt... Deswegen bin ich mal weiter gegangen und siehe da:BlackJack hat geschrieben:@jens: Da scheint es ein Muster zu geben, dass sich der Wert immer bei einer 2er-Potenz ändert.

Immerhin, scheint das "mantissa sign" sich richtig zu verhalten...
Ich hab auch mal mit meine Code folgendes gemacht:
Code: Alles auswählen
for i in xrange(0x100):
fp = BASIC09FloatingPoint(i)
print "%3s -> %s" % (
i,
" ".join(["$%02x" % i for i in fp.get_bytes()])
)120 -> $87 $f0 $00 $00 $00 $00
121 -> $87 $f2 $00 $00 $00 $00
122 -> $87 $f4 $00 $00 $00 $00
123 -> $87 $f6 $00 $00 $00 $00
124 -> $87 $f8 $00 $00 $00 $00
125 -> $87 $fa $00 $00 $00 $00
126 -> $87 $fc $00 $00 $00 $00
127 -> $87 $fe $00 $00 $00 $00
128 -> $88 $80 $00 $00 $00 $00
129 -> $88 $80 $80 $00 $00 $00
130 -> $88 $82 $00 $00 $00 $00
131 -> $88 $82 $80 $00 $00 $00
132 -> $88 $84 $00 $00 $00 $00
133 -> $88 $84 $80 $00 $00 $00
134 -> $88 $86 $00 $00 $00 $00
- jens
- Python-Forum Veteran
- Beiträge: 8502
- Registriert: Dienstag 10. August 2004, 09:40
- Wohnort: duisburg
- Kontaktdaten:
Ich hab mal Spaßeshalber einen kompletten Durchlauf von 0-255 gemacht:jens hat geschrieben:So, hab nun mal meine Daten mit den aus BASIC09 (meine Emulierte Version) verglichen:
Getestet habe ich mit diesen Werten: 0, 1, 2, 126, 127, 128, 129, 130, 253, 254, 255
Übereinstimmung der Werte habe ich bei: 1, 2, 126, 127, 128, 130, 254
Unterschiedliche Werte bei: 0, 129, 253, 255
OK: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 130, 132, 134, 136, 138, 140, 142, 144, 146, 148, 150, 152, 154, 156, 158, 160, 162, 164, 166, 168, 170, 172, 174, 176, 178, 180, 182, 184, 186, 188, 190, 192, 194, 196, 198, 200, 202, 204, 206, 208, 210, 212, 214, 216, 218, 220, 222, 224, 226, 228, 230, 232, 234, 236, 238, 240, 242, 244, 246, 248, 250, 252, 254]
Failed: [0, 129, 131, 133, 135, 137, 139, 141, 143, 145, 147, 149, 151, 153, 155, 157, 159, 161, 163, 165, 167, 169, 171, 173, 175, 177, 179, 181, 183, 185, 187, 189, 191, 193, 195, 197, 199, 201, 203, 205, 207, 209, 211, 213, 215, 217, 219, 221, 223, 225, 227, 229, 231, 233, 235, 237, 239, 241, 243, 245, 247, 249, 251, 253, 255]
Interessantes Muster
- jens
- Python-Forum Veteran
- Beiträge: 8502
- Registriert: Dienstag 10. August 2004, 09:40
- Wohnort: duisburg
- Kontaktdaten:
So, nach den letzten Bugfixes [1,2] geht es nun für Glanzzahlen von $0-$ffff:
[1] https://github.com/jedie/DragonPy/commi ... 3e885ed002
[2] https://github.com/jedie/DragonPy/commi ... d5f4a60d28
Nun würde ich gern mal sehen, was passiert, wenn ich versuche Divisionen vor zu nehmen... Ich denke mal ich werde auf unterschiedliche Rundungsfehler stoßen...
[1] https://github.com/jedie/DragonPy/commi ... 3e885ed002
[2] https://github.com/jedie/DragonPy/commi ... d5f4a60d28
Nun würde ich gern mal sehen, was passiert, wenn ich versuche Divisionen vor zu nehmen... Ich denke mal ich werde auf unterschiedliche Rundungsfehler stoßen...
-
BlackJack
Ich habe mal spasseshalber Konvertierungsfunktionen für die beiden C64-BASIC Fliesskommazahlenformate geschrieben:
Code: Alles auswählen
from __future__ import print_function
import math
from struct import Struct
MFLOAT_STRUCT = Struct('>BI')
FAC_FLOAT_STRUCT = Struct('>BIb')
assert MFLOAT_STRUCT.size == 5 and FAC_FLOAT_STRUCT.size == 6
def _float2cbm_float(value):
sign = 0
mantissa, exponent = math.frexp(value)
if mantissa or exponent:
exponent += 128
if not 0 <= exponent <= 255:
raise OverflowError
if mantissa < 0:
mantissa = -mantissa
sign = 1
mantissa = mantissa * 2**32
return exponent, int(mantissa + 0.5), sign
def float2cbm_mfloat(value):
exponent, mantissa, sign = _float2cbm_float(value)
return MFLOAT_STRUCT.pack(exponent, (mantissa & 0x7fffffff) | (sign << 31))
def float2cbm_fac_float(value):
exponent, mantissa, sign = _float2cbm_float(value)
return FAC_FLOAT_STRUCT.pack(exponent, mantissa, -1 if sign else 0)
def cbm_float2float(value):
if len(value) == 5:
exponent, mantissa = MFLOAT_STRUCT.unpack(value)
sign = mantissa >> 31
if exponent:
mantissa |= 0x80000000
elif len(value) == 6:
exponent, mantissa, sign = FAC_FLOAT_STRUCT.unpack(value)
else:
raise ValueError('wrong byte length for a cbm float')
result = mantissa * 2.0**(exponent - 128 - 32)
return -result if sign else result
def main():
for value in [
0, 0.5, 0.1, -1, -0.25, 100, -1000, -42.23, 3.141592653589793, 10e200
]:
mfloat = float2cbm_mfloat(value)
fac_float = float2cbm_fac_float(value)
py_float_a = cbm_float2float(mfloat)
py_float_b = cbm_float2float(fac_float)
print(
mfloat.encode('hex'),
fac_float.encode('hex'),
value,
py_float_a,
py_float_a == py_float_b,
value - py_float_a
)
if __name__ == '__main__':
main()