double als Hex-Dump ausgeben



  • Hallo,

    ich möchte zu Debug-Zwecken einen double-Wert (64 bit float) als Hex ausgegeben bekommen.

    Die naheliegenste Methode mit

    sprintf("%x", meinedouble);
    

    funktioniert leider nicht, da nur 32 Bit ausgegeben werden.

    Wie bekomme ich das Ausgegeben?

    Danke

    Hintergrund:
    Ich habe ein Dateiformat, welches verschiedene NaN-Darstellung als inband-Signalisierung nutzt und diese muss ich mir selbst erstmal signalisieren.



  • Wie wär's mit nem reinterpretcast<char*>(&deinDouble), dann haste nen pointer auf das Teil, der aber auf chars arbeitet. Mit Den Indizes 0 bis sieben kannste dann die einzelnen bytes ausgeben. Daß das nicht portabel ist brauche ich wohl nicht dazusagen, oder?



  • #include <algorithm>
    #include <iostream>
    #include <iterator>
    
    struct BytePrinter
    {
        BytePrinter( char c ) : m_c( c ) {}
        unsigned char m_c;
    };
    std::ostream& operator<<( std::ostream& out, const BytePrinter& bp )
    {
        return out << unsigned( bp.m_c );
    }
    
    int main()
    {
        using namespace std;
        double d = 3.14;
        const char* p = reinterpret_cast< const char* >( &d );
        copy( p, p + sizeof( double ), ostream_iterator< BytePrinter >( cout << hex, " " ) );
        cout << endl;
        return 0;
    }
    

    Gruß
    Werner



  • Vielen Dank, auf diese Weise habe ich herausgefunden, dass mein gesuchter Wert:

    00 00 00 00 00 00 f8 7f
    

    ist.
    Das ist +NAN.

    Nun muss ich double-Variablen mit diesem Wert belegen, wie schafft man das?
    reinterprete_cast<>() und ein c-typecast von long unsigned int nach double hilft mir da nicht weiter.

    Ich muss irgendwie direkt die Bits der Float-Variable verrücken.
    Über Pointer könnte man etwa so den Compilter austricksen:

    double d;
    
    unsigned long int* i;
    i= (unsigned long int*) &d;
    
    (*i)= 0xf87f;
    

    Trotzdem ist das ersten unschön und zweitens muss ich irgendwie sicherstellen, dass ich immer ein 64-Bit Integer habe.

    PS: Über den Sinn der aktiven Ausnutzung von NaN-Werten müssen wir hier nicht streiten, ich muss diese leider in einem Datenformat auswerten und schreiben.



  • Wenn du direkt auf der Byte-Struktur hantieren willst, kommst du um solche Zeiger-Verknotungen wohl kaum herum. Aber vielleicht ist es für deine Zwecke einfacher, die Möglichkeiten des C++ Standards zu nutzen:

    #include <limits>
    double nan_val = std::numeric_limits<double>::quiet_nan();
    

    (im Gegensatz zu deiner "Spielerei" ist das sogar portabel)



  • Vielen Dank für die schöne Lösung.
    Leider ist das in meinem Borland Builder 6 nicht implementiert:

    //[...]
    return std::numeric_limits<double>::quiet_NaN();
    

    ergibt:

    Unresolved external '_STL::_D_qNaN'
    

    Mich wundert sowieso, dass man dieses NaN verwendet und sogar darauf prüft, da NaN nie gleich NaN sein kann.



  • Kann ich nicht nachvollziehen. Ich habe auch den BCB6 und da funktioniert es.



  • Was mache ich falsch?

    Mein Linker-Fehler lässt sich auch reproduzieren, wenn man eine neue Consolen-Anwendung mit folgendem Inhalt erstellt:

    #include <limits>
    
    void main(void)
      {
      double d;
      d= std::numeric_limits<double>::quiet_NaN();
      }
    


  • NaN != nan (?)

    Gross/Kleinschreibung des Helfers evtl. so wie angegeben übernehmen 😉



  • lieber nicht. Die Funktion heißt nämlich so. quiet_NaN()



  • @markus.r
    Arbeitest du mit oder ohne dynamische RTL?
    Ohne scheint es zu gehen.



  • @Braunstein

    Genau das ist es: Schalte ich dynamisches RTL aus, funktioniert es.

    Statisches Linken könnte sich auch bei der Softwareverteilung als nützlich erweisen.

    Vielen Dank für die Hilfe.


Anmelden zum Antworten