float nach binary...
@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...
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()