int24 nach long double



  • Hallo, ich habe zwei Fragen:

    Zum einen habe ich signed integer mit 24 Bit. Die möchte ich nach "long double" konvertieren. Hier ist mein Ansatz:

    if(int24Val & 0x800000) {
         longDoubleVal = (int24Val | ~0xffffff);
    } else {
         longDoubleVal = int24Val;
    }
    

    Das gleiche habe ich entsprechend für int48 implementiert. Frage: Ist das so in Ordnung, oder kann je nach Plattform z.B. das Problem auftreten, dass negative Zahlen nicht mit führenden 1er Bits beginnen?

    Hierzu die zweite Frage:
    Der Größte Wert, der bei mir auftreten kann, ist ein signed int64. Kann ich absolut gefahrlos einen std::int64_t in einen long double packen?

    longDoubleVal = int64Val;
    

    Vielen Dank 🙂


  • Mod

    Kann ich absolut gefahrlos einen std::int64_t in einen long double packen?

    Klar. Nur kann ggf. nicht jeder Ganzzahlwert von einem long double genau dargestellt werden. Auf meiner (64-Bit) Platform ist ein long double groß genug (16 Bytes), aber möglicherweise nicht auf deiner.

    Zum einen habe ich signed integer mit 24 Bit.

    Ist das ein fundamentaler Typ, der von der Implementierung bereitgestellt wird? Oder eine Klasse, die ein Bitfield hat?



  • Arcoth schrieb:

    Zum einen habe ich signed integer mit 24 Bit.

    Ist das ein fundamentaler Typ, der von der Implementierung bereitgestellt wird? Oder eine Klasse, die ein Bitfield hat?

    Vielleicht gibt es ja einen besseren Ansatz, aber es sieht momentan so aus:

    Ich bekomme alle Werte in Form eines Bytestromes und da die maximale Größe std::int64_t ist, packe ich jeden Wert erst einmal in einen std::int64_t. Ich kenne aber den wahren Typ, z.B. int24, int32 oder eben int64. Außerdem gibt es noch einen Faktor, der zusätzlich übertragen wird. Was mache ich also?

    Je nach Typ konvertiere ich entsprechend alle Werte in den "long double", worauf ich anschließend den Faktor anwende. Beispiel:

    int8: 17
    faktor: 0.1
    
    long double echterWert = 17;
    echterWert *= 0.1;
    

    Das funktioniert auch bei allen Werten. Nur der int64 fällt aus dem Rahmen.



  • Nun, dann hängt die Codierung deiner Werte sowieso nicht von der Plattform ab, sondern von deinem Bytestrom.



  • Deine sign extension funktioniert allerdings unabhängig davon nur unter der Annahme, dass die Plattform das Zweierkomplement benutzt. Es gibt zwar keine relevante Plattformen, wo das anders wäre, aber prinzipiell müsstest du wohl den Betrag deiner 24 bit-Zahl ausrechnen und dann erst über operator- negativ machen.



  • Ich würde die Sign-Extension auf jeden Fall schon beim Einlesen machen, und nicht erst wenn du nach long double konvertierst.

    Also dort wo du dir einen int64_t aus den einzelnen Bytes bastelst.
    Ob du das dann plattformneutral machst oder dich auf 2's complement festlegst bleibt dir überlassen. Bei nem Privatprojekt würd' ich mir vermutlich die Zeit nehmen es plattformneutral zu machen - einfach nur so, weil das "schöner" ist.
    Wenns für die Arbeit wäre würd ich mich aber sicher einfach auf 2's complement verlassen - dafür dass ich Probleme löse die gar nicht da sind zahlt mich meine Firma nicht 😉



  • hustbaer schrieb:

    Ich würde die Sign-Extension auf jeden Fall schon beim Einlesen machen, und nicht erst wenn du nach long double konvertierst.

    Du meinst ich sollte das MSB betrachten (kommt zuerst) und direkt auf das Vorzeichenbit prüfen? Falls ja, int64_t negieren und von rechts die Bytes reinschieben?

    😕 😋


Anmelden zum Antworten