float nach binary...

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
BlackJack

@jens: Da scheint es ein Muster zu geben, dass sich der Wert immer bei einer 2er-Potenz ändert. :-)
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

BlackJack hat geschrieben:@jens: Da scheint es ein Muster zu geben, dass sich der Wert immer bei einer 2er-Potenz ändert. :-)
Stimmt... Deswegen bin ich mal weiter gegangen und siehe da:

Bild

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()])
        )
Nur ein Ausschnitt:
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

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

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
Ich hab mal Spaßeshalber einen kompletten Durchlauf von 0-255 gemacht:
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 :P

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
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...

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
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()
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Das ist natürlich wesentlich eleganter, als meine Lösung ;)

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Antworten