double a -> char array[sizeof(double)] ???



  • HI,
    Ich würde gerne eine Funktion schreiben, welche alle typen in ein char array schreiben kann. Für int ist es kein Problem, aber double macht Probleme =(.
    Kennt jemand eine gute Lösung ??
    Gruß



  • Zeig mal, was du da mit den int's machst.. Das kommt mir sehr supsekt vor.. 🙄



  • Trau mich nicht. *ggg*



  • Grundsätzlich wieder mal die nervige Frage: Wozu brauchst du das? 😉

    (Sollte vor allem dazu dienen, dass du dir nicht irgendwelche Frickellösungen und -wege aneignest, nur weil dir keine Alternativen bekannt sind.)



  • Ich muß den int in ein char array schreiben. Eben jedes Byte für sich.
    Und dannach wieder rausschreiben in ein int.
    Gruß



  • Ich habe eine write Funktion. Die schreibt in Dateien.
    Und die kriegt ein char *. Und da müssen jetzt die typen konvertiert werden.



  • Mach das lieber so:

    #include <sstream>
    
    std::stringstream s;
    double a = 5.0;
    
    s << a;
    
    write ( s.str().c_str() );
    

    std::stringstream konvertiert dir alle Typen, die du reinschiebst automatisch und dann holst du dir per ::str einen std::string und dann per ::c_str() eben ein char Array.



  • @drakon
    Danke. Hab das schon ziemlich oft so gemacht, aber gerade bin ich nicht drauf gekommen.
    Wahnsinn.
    Gruß



  • Mal auf die gefahr hin das ich gelüncht werde 🙂
    Mir schwebt irgendwie sowas vor:

    int x;          //Die zu konvertierende Zahl
    char *x_ptr=reinterpret_cast<char *>(&x); //Ein Pointer dessen adrese byteweise erhöht wird
    
    for(unsigned int count=0;count < sizeof(x) count++)
       *(x_ptr+count)
    

    Geht aber noch nicht. Und ich weiß nicht so richtig warum
    Gruß

    P.s.
    Bitte lünchen ersparen, bin nicht sadomistisch veranlagt *ggg*



  • Was passt dir denn an der oben genannten Methode nicht??



  • @Drakon
    -Mir ist zu spät aufgefallen, dass ich in dem Codeabschnitt wo ich mich gerade befinde keinen speicher merh anfordern darf.
    Wenn isch std::stringstream auch richtig initialisiere, glaube ich trotzdem, dass
    die Methode c_str neuen braucht.
    -Des weitern benötige ich eine Binäre umrechnung.
    Bei deiner Methode bekomme ich
    x=100;
    char a[3];
    a[0]=1;
    a[1]=0;
    a[2]=0;
    Ich würde benötigen:
    100=0x64=0000 0000 0110 0100
    a[0]=0000
    a[1]=0000
    a[2]=0110
    a[3]=0100
    Wobei die Konvertierung ja einfach dein a c_string -'0' wäre.
    -Ich bin der überzeugung, dass wenn der cast nach char* läuft,
    das fast nicht effizienter gemacht werden kann

    Gruß



  • Ich habs, lesen mit

    (*(x_ptr+count)&0x0FF);
    

    geht dann
    Gruß


  • Mod

    AlexXXx schrieb:

    Ich habs, lesen mit

    (*(x_ptr+count)&0x0FF);
    

    geht dann
    Gruß

    Besser wäre, von vornherein unsigned char zu verwenden.
    *(x_ptr+count)
    ist nicht falsch, nur hast du möglicherweise falsche Erwartungen.

    memcpy gibt es auch noch.



  • Also so gehts ganz gut:

    int x=-999999;
    
        char *x_ptr=reinterpret_cast<char *>(&x);
        unsigned char ar[sizeof(x)];
    
        std::cout <<"\nx " <<x;
    
        for(unsigned int count=0;count<sizeof(x);count++)
            ar[count]=(int)(*(x_ptr+count) & 0x0FF);
    
        x=0;
    
        for(int count=sizeof(x)-1;count>=0;count--)
         {
            x=x << 8;    
            x|=ar[count];
         }
        std::cout <<"\nx " <<x;
    


  • @camper
    Ja du hast Recht, memcpy wäre eine lösung.
    Würds gern so noch ein bisschen weiter versuchen zum üben.
    Was muß ich denn für double machen ??
    double nach unsigned long int casten und dann wie vorher ??
    Gruß


  • Mod

    AlexXXx schrieb:

    ar[count]=(int)(*(x_ptr+count) & 0x0FF);
    

    Das funktioniert, macht aber nicht den Eindruck, als dir wirklich bewusst ist, was hier passiert. Der Cast und das & 0xFF sind völlig überflüssig (naja, nicht ganz im Allgemeinen, im Extremfall ist allerdings auch dein Konstrukt nicht korrekt).
    Wieso nicht einfach x_ptr ebenfalls als unsigned char*?

    Ich vermute mal, dass char bei dir vorzeichenbehaftet ist, und dann mitunter negative Zahlen entstehen, mit denen du nicht gerechnet hast?



  • @camper,
    Doch mir ist schon klar was passiert.
    Dass es überflüssig ist merk ich jetzt auch. Aber wies so ist, man tastet sich an den code ran.
    Dass MSB Vorzeichen ist ist klar.
    count mit unsigned char aufrufen ist besser. Stimmt schon.
    Ändert aber nichts an den Werten im Speicher.

    Wenn mir was unklar ist, freu ich miich wenn dus mir erklärst, glaube es abernicht. 🙂
    P.s.: char ist bei mir nicht mehr vorzeichen behaftet gewesen.
    0x0FF hab ich vergessen raus zu machen. Da hst du schon Recht.

    Aber wie bekomme ich das mit gleitkomazahlen hin. Wei0t du was ??
    Fang jetzt bitte nicht an mit ich weiß nicht wie die aufgebaut sond oder sowas.
    Wenni ch was nicht weiß, frage ich. (Das ist glaub erstes Semester gewesen )

    Gruß



  • So ists besser. 🙂

    int x=-99;
    
        char *x_ptr=reinterpret_cast<char *>(&x);
        unsigned char ar[sizeof(x)];
    
        std::cout <<"\nx " <<x;
    
        for(unsigned int count=0;count<sizeof(x);count++)
            ar[count]=*(x_ptr+count) ;
    
        x=0;
    
        for(int count=sizeof(x)-1;count>=0;count--)
         {
            x=x << 8;
            x|=ar[count];
         }
    


  • So gehts auch für double. Ist glaub gut so.

    double x=0.999;
    
        char *x_ptr=reinterpret_cast<char *>(&x);
        unsigned char ar[sizeof(x)];
    
        std::cout <<"\nx " <<x;
    
        for(unsigned int count=0;count<sizeof(x);count++)
            ar[count]=*(x_ptr+count) ;
    
        x=0;
    
        for(int count=sizeof(x)-1;count>=0;count--)
            *(x_ptr+count)|=ar[count];
    
        std::cout <<"\nx " <<x;
    


  • AlexXXx schrieb:

    int x=-99;
    
        char *x_ptr=reinterpret_cast<char *>(&x);
        unsigned char ar[sizeof(x)];
    
        std::cout <<"\nx " <<x;
    
        for(unsigned int count=0;count<sizeof(x);count++)
            ar[count]=*(x_ptr+count) ;
    
        x=0;
    
        for(int count=sizeof(x)-1;count>=0;count--)
         {
            x=x << 8;
            x|=ar[count];
         }
    

    Was soll'n das werden, wenn's fertig ist? Die Kodierung passt überhaupt nicht zur Dekorierung. Das ist sowas von un-portabel, dass es nicht mal auf ein und demselben Rechner funktionieren muss.

    Das hier wäre wenigstens konsistent:

    void ich_scheiss_auf_portabel__nach_mir_die_sintflut() {
      int foo = 23;
      char dings[sizeof(foo)];
      std::memcpy(dings,&foo,sizeof(dings)); // foo --> dings
      std::memcpy(&foo,dings,sizeof(foo)  ); // dings --> foo
    }
    

    Der Haken: Solltest Du dings in eine Datei schreiben und auf einem anderen Rechner einer anderen Gattung wieder lesen wollen, wird das eventuell wieder nicht funktionieren.

    Wenn Du vorhast plattformunabhängige Binärdateien zu schreiben, solltest Du das anders machen. Zum Beispiel unsigned ints manuell durch Shiften und Maskieren in unsigned chars zerlegen und wieder zurück.

    Es gibt da übrigends noch so eine "Aliasing"-Regel, die man mit reinterpret_cast leicht verletzen kann. In Deinem Fall geht das noch in Ordnung, da Zeiger auf char bzw unsigned char auf alles zeigen dürfen.

    Gruß,
    SP


Anmelden zum Antworten