Seite 1 von 2

Re: float nach binary...

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

Re: float nach binary...

Verfasst: Dienstag 8. Juli 2014, 16:46
von jens
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

Re: float nach binary...

Verfasst: Dienstag 8. Juli 2014, 16:53
von jens
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

Re: float nach binary...

Verfasst: Freitag 11. Juli 2014, 12:57
von jens
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...

Re: float nach binary...

Verfasst: Donnerstag 17. Juli 2014, 09:57
von 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()

Re: float nach binary...

Verfasst: Donnerstag 17. Juli 2014, 10:21
von jens
Das ist natürlich wesentlich eleganter, als meine Lösung ;)