Byte zu float

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.
Tulkas
User
Beiträge: 1
Registriert: Montag 6. Dezember 2004, 14:00

Byte zu float

Beitragvon Tulkas » Montag 6. Dezember 2004, 14:25

Hallo.
Ich hab ein kleines Problem mit der Zahlenkonvertierung. Via serieller Schnittstelle bekomme ich 4 8-Bit-Zahlen, die ich in ein Array schreibe. Diese 4x1Byte ist eine Zahl. Bei Integern ist das auch nicht weiter schwer, diese in die ursprüngliche Zahl zurückzuführen:

Code: Alles auswählen

def makeAtoInt4(self, bytearray):
        """Wandelt 4x8-Bit in 32-Bit Werte um"""
        int32_0 = bytearray[0] << 24
        int32_1 = bytearray[1] << 16
        int32_2 = bytearray[2] << 8
        int32_3 = bytearray[3]
        int32 = in32_0 + int32_1 + int32_2 + int32_3
        return int32

Aber wie realisiere ich es in Python, daß aus 4 bytes ein float wird?

Danke
Tulkas

P.S.
Mit C würde ich es so machen:

Code: Alles auswählen

typedef union
{
   float   f;
   int     l;
   short int i[2];
   char    b[4];
}U32;

U32 int32;
int32.b[0] = bytearray[0]
int32.b[1] = bytearray[1]
int32.b[2] = bytearray[2]
int32.b[3] = bytearray[3]

printf("Float: %f\n", int32.f);
Gibts sowas wie "union" vielleicht auch in Python?
Benutzeravatar
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

Beitragvon Dookie » Montag 6. Dezember 2004, 16:12

Hi Tulkas,

da gibts gleich mehrere Probleme:
1. Nein Python kennt kein Union, währ bei der dynamischen Typebehandlung von Python auch schwer zu realisieren.
2. Pythons Float-Typ ist eigenlich ein Longfloat mit 64 Bit.
3. Welches Format hat der Floattyp den du da via serieller Schnittstelle bekommst (Vorzeichen, Exponent, Mantisse, Big- oder Littleendian)

Falls das Format dem IEEE-Standard 754-1985 entspricht könntest Du folgende Funktion verwenden:

Code: Alles auswählen

def makeAtoFloat(self, bytearray):
    int4 = self.makeAtoInt4(bytearray)
    sign = (1, -1)[int4 >> 31 & 1] # edit: & 1 added
    exp = int4 >> 23 & 255
    if exp >= 128:
        exp = -((exp ^ 255) + 1) # edit: -(...) added
    mant = int4 & 8388607 # 2 ** 23 - 1
    float32 = sign * mant ** exp
    return float32

nicht getestet, sollte aber klappen

Gruß

Dookie

Code: Alles auswählen

#!/usr/bin/env python
import this
Gast

Beitragvon Gast » Montag 6. Dezember 2004, 18:37

Dookie hat geschrieben:Hi Tulkas,

da gibts gleich mehrere Probleme:
1. Nein Python kennt kein Union, währ bei der dynamischen Typebehandlung von Python auch schwer zu realisieren.

Das hatte ich schon befürchtet.

Dookie hat geschrieben:3. Welches Format hat der Floattyp den du da via serieller Schnittstelle bekommst (Vorzeichen, Exponent, Mantisse, Big- oder Littleendian)

Das weiß ich (noch) nicht. Da muß ich erst in das Datenblatt des µC-C-Compilers schauen.
Vielen Dank für deine Antwort, die werd' ich in Bälde ausprobieren :)

Gruß
Tulkas
Benutzeravatar
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

Beitragvon Dookie » Montag 6. Dezember 2004, 19:40

Hi nochmal,

das ganze ist doch noch etwas komplizierter.
aber zum Glück gibts ja das Modul struct :)

Code: Alles auswählen

import struct

def a_to_int(bytearray):
    return struct.unpack("l", bytearray)[0]

def a_to_float(bytearray):
    return struct.unpack("f", bytearray)[0]

Bytearray muss hier jeweils ein String der Länge 4 sein.

Gruß

Dookie

Code: Alles auswählen

#!/usr/bin/env python
import this
Gast

Beitragvon Gast » Mittwoch 8. Dezember 2004, 14:41

Vielen Dank.
Mit dem Modul "struct" klappts jetzt...

Gruß
Tulkas

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder