Re: float nach binary...
Verfasst: Dienstag 8. Juli 2014, 16:26
@jens: Da scheint es ein Muster zu geben, dass sich der Wert immer bei einer 2er-Potenz ändert. 

Seit 2002 Diskussionen rund um die Programmiersprache Python
https://www.python-forum.de/
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.
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
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
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()