Typumwandlung: int -> char[4]



  • Ich möchte den Integer nicht in einen String umwandeln oder formatieren, sondern in ein char[4] konvertieren.



  • pmw schrieb:

    ACData[i] = ((char*)ITest)[i];
    

    mach daraus

    ACData[i] = ((char*)&ITest)[i];
    

    man beachte das '&' 😉
    dann sollte es gehen



  • typedef union {
      int Integer;
      char bytes[4];
    } IntToChar4;
    

    und dann

    IntToChar4 buf;
    buf.Integer = /*intVariable*/;
    

    und in buf.bytes steh'n die chars drin

    //EDIT:
    Wie lang Tipp ich denn? 😮 😮



  • Hi!

    Danke für die Hilfe. Der Vorschlag von net klappt einwanfrei. Allerdings verstehe ich nicht, warum hier die Referenz auf die Variabel notwendig ist. Wie funktioniert der umgekehrte Weg?

    Das geht leider nicht:

    ((char*)&ITest)[i] = ACData[i];
    

    Viele Grüße
    pmw



  • pmw schrieb:

    Allerdings verstehe ich nicht, warum hier die Referenz auf die Variabel notwendig ist.

    nein, das ist der adressoperator (adresse von ...). referenzen gibbets nicht in c.

    pmw schrieb:

    Wie funktioniert der umgekehrte Weg?
    Das geht leider nicht:

    ((char*)&ITest)[i] = ACData[i];
    

    so...

    *&ITest = *(int*)ACData;
    

    aber ohne schleife 😉



  • Gibt es auch die Möglichkeit die Zuweisen Byte weise zu machen?



  • pmw schrieb:

    Gibt es auch die Möglichkeit die Zuweisen Byte weise zu machen?

    wie in meinem ersten beitrag, nur musste das links und rechts vom '=' vertauschen



  • net schrieb:

    so...

    *&ITest = *(int*)ACData;
    

    Und noch einfacher

    ITest = *(int*) ACData;
    


  • groovemaster schrieb:

    net schrieb:

    so...

    *&ITest = *(int*)ACData;
    

    Und noch einfacher

    ITest = *(int*) ACData;
    

    mann, bin ich doof 😮



  • Vielen Dank für die gute und schnelle Hilfe!!!

    🙂 🙂 🙂 🙂 🙂 🙂 🙂 🙂 🙂 🙂



  • typedef union { 
      int Integer; 
      char bytes[4]; 
    } IntToChar4;
    

    Das ist höchstwarscheinlich nicht Standardkonform - dass das klapt liegt höchst wahrscheinlich an deinem Compiler (mit MSVC Net 2003 kann man es so machen - aber ich vermutte das dass kein Standard ist)

    zum Problem:
    ich würde einfach Bitoperationen verwenden - die wären sicherlich schöner als das Rumtricksen mit Zeigern



  • Ein int besteht aus sizeof(int) * 8 Bits

    Ein char besteht aus sizeof(char) * 8 Bits

    Zunächst stellt sich die doch erst die Frage ob ein int vier chars passt (C99 definiert doch nicht das ein int in vier chars passt - oder?):
    Falls siezof(int) / sizeof(char) == 4 (true) gleich eins ist, dann ja

    (Dein Programm könnte ja auf einem Rechner ausgeführt werden, der andere Größen für Datentypen bereit stellt – obwohl das extrem unwahrscheinlich ist, bzw. du weißt auf welchen Rechnern das Programm später ausgeführt wird)

    Die einzelnen Bits von dem Integer nummeriere ich von Rechts nach Links beginnend mit der 0. Das niederwertigste Bit bezeichne ich mit dem Index 0 – das höchstwertige Bit mit dem Index n

    Ein Integer hat n Bits: BitSizeOfInt = sizeof(int) * 8
    Der vierte Teil davon ist: BitSizeOfChar = sizeof(char) * 8; oder SizeOfInt / 4;

    n, …, 9,8,7,6,4,3, 2, 1, 0

    Nun teile ich den Integer in vier gleich große Stücke auf

    Den erste Teil des Integer geht von n bis n-BitSizeOfChar+1
    Der zweite von n-SizeOfChar bis n-2SizeOfChar+1
    Der dritte geht von n-2*SizeOfChar bis n-3*SizeOfChar+1
    Der vierte geht von n-3
    SizeOfChar bis 0

    Nun legen wir ein char Array an: char Array[4]; // Array ist nicht der beste Name

    BTW: In C99 gibt es auch den // Komentar:
    “Except within a character constant, a string literal, or a comment, the characters //
    introduce a comment that includes all multibyte characters up to, but not including, the
    next new-line character“

    Den ersten Teil des Integer packe ich in die Variable Array[0]:

    Dazu ist eine Rechtsverschiebung von 3*BitSizeOfChar Bist notwendig
    (man braucht sich hier keine Gedanken machen ob man es mit einem unsinged oder einem signed char zu tun hat – an der internen Bit Repräsentation ändert sich nichts – nur der Wert von Array[0] wird anders interpretiert – definiert der C Standard überhaupt ob ein char signed oder unsigned ist? – in C++98 ist das nicht so – dort ist nicht definiert ob ein char signed oder unsigned ist)

    int zahl;
    Array[0] = zahl >> 3*BitSizeOfChar; // der >> hat ein geringere Priorität als der * Operator - zur bessern Lesbarkeit sollte man trotzdem Klammern
    Array[1] = zahl >> 2*BitSizeOfChar;
    Array[2] = zahl >> 1*BitSizeOfChar;
    Array[3] = zahl;
    

    Eine Frage die sich noch stellt – was passiert wenn man einem char einen Int Wert zuweißt?
    Angenommen ein int ist 32 Bit groß und ein char 8 Bit – dann werden die Bits 32 bis 9 vom Integer verworfen und nur die Bits von 8 bis 0 in den char übertragen

    Statt Rechtsverschieben und Linksverschieben kann man auch mit 2er Potenzen multiplizieren – vielleicht ist dass sogar schneller – auch wenn das früher genau anders herum war – müsste man mal testen ob Shiften um 4 Bits schneller oder langsammer ist als die Multiplikation mit 16

    Das ganze habe ich nicht getestet und vielleicht habe ich einen schwerwiegenden Fehler mit eingebaut – glaub jedoch das es so ungefähr funktioniert



  • Vertexwahn schrieb:

    Ein int besteht aus sizeof(int) * 8 Bits

    Ein char besteht aus sizeof(char) * 8 Bits

    Nörgler würden sagen, dass ein char nicht zwingend aus 8 Bits besteht. Das betrifft aber nur absolute Exoten.

    Vertexwahn schrieb:

    Zunächst stellt sich die doch erst die Frage ob ein int vier chars passt (C99 definiert doch nicht das ein int in vier chars passt - oder?):

    Richtig, der Standard sagt nichts darüber aus, wie groß ein int ist, lediglich dass es >= short ist.

    Vertexwahn schrieb:

    Falls siezof(int) / sizeof(char) == 4 (true) gleich eins ist, dann ja

    Das sizeof(char) kannst du dir sparen, denn es ist immer 1. Das ist vom Standard definiert.

    Vertexwahn schrieb:

    ...

    Unabhängig davon ob es funktioniert oder nicht. Aber wäre es mit memcpy() nicht schneller erledigt?



  • > The sizeof operator yields the size (in bytes) of its operand, which may be an expression or the parenthesized name of a type.

    > When applied to an operand that has type char, unsigned char, or signed char,
    (or a qualified version thereof) the result is 1.

    soll das jetzt heißen ein char ist immer ein Byte groß?

    mmh dann könnte sizeof(char) einen anderen wert haben wie:
    char array[10];
    sizeof(array[0]);

    oder?



  • TactX schrieb:

    Vertexwahn schrieb:

    Ein int besteht aus sizeof(int) * 8 Bits

    Ein char besteht aus sizeof(char) * 8 Bits

    Nörgler würden sagen, dass ein char nicht zwingend aus 8 Bits besteht. Das betrifft aber nur absolute Exoten.

    Naja, der Standard würde es eher so schreiben:
    Ein int besteht aus 'sizeof(int) * CHAR_BIT' Bits.
    Ein char besteht aus 'sizeof(char) * CHAR_BIT' bzw. 'CHAR_BIT' Bits.
    🙂

    Vertexwahn schrieb:

    müsste man mal testen ob Shiften um 4 Bits schneller oder langsammer ist als die Multiplikation mit 16

    Sehr unwahrscheinlich, dass Shiften langsamer ist, vielleicht auf irgendwelchen Exoten.

    Vertexwahn schrieb:

    Angenommen ein int ist 32 Bit groß und ein char 8 Bit – dann werden die Bits 32 bis 9 vom Integer verworfen und nur die Bits von 8 bis 0 in den char übertragen

    Nicht ganz. Da int hier nur 32 Bits hat, wird ein gängiger Prozessor Bit 0 bis 7 ins char kopieren und Bit 8 bis 31 verwerfen. Abhängig davon, ob char signed oder unsigned ist, werden noch entsprechende Anpassungen vorgenommen.

    @Vertexwahn
    Könntest du dir mal bitte angewöhnen, ordentlich zu quoten?



  • C99:

    Values stored in non-bit-field objects of any other object type consist of n * CHAR_BIT bits, where n is the size of an object of that type, in bytes.

    Ich dachte eine Byte hat immer 8 Bit

    Könntest du dir mal bitte angewöhnen, ordentlich zu quoten?

    ich versuchs 😉 - wie ersetze ich "Zitat" durch einen Namen?



  • groovemaster schrieb:

    Vertexwahn schrieb:

    müsste man mal testen ob Shiften um 4 Bits schneller oder langsammer ist als die Multiplikation mit 16

    Sehr unwahrscheinlich, dass Shiften langsamer ist, vielleicht auf irgendwelchen Exoten.

    Der P4 ist ein Exot? 😮

    Der P4 hat keinen Barrel Shifter. Viele Leute sagen, dass er auch deswegen so lahm ist...



  • Vertexwahn schrieb:

    ich versuchs 😉 - wie ersetze ich "Zitat" durch einen Namen?

    Indem du in das Editfeld hinter dem Quote Button einen Namen reinschreibst.

    TactX schrieb:

    Der P4 hat keinen Barrel Shifter. Viele Leute sagen, dass er auch deswegen so lahm ist...

    Whoa, das hört sich ja ziemlich übel an. Naja, dazu kann ich leider nix sagen, weil ich meinen letzten Pentium '00 zu Grabe getragen hab. Aber normalerweise sollte sich Shiften auf Hardwareebene schon schneller realisieren lassen wie Multiplikationen, oder zumindest nicht langsamer.



  • groovemaster schrieb:

    TactX schrieb:

    Der P4 hat keinen Barrel Shifter. Viele Leute sagen, dass er auch deswegen so lahm ist...

    Whoa, das hört sich ja ziemlich übel an. Naja, dazu kann ich leider nix sagen, weil ich meinen letzten Pentium '00 zu Grabe getragen hab. Aber normalerweise sollte sich Shiften auf Hardwareebene schon schneller realisieren lassen wie Multiplikationen, oder zumindest nicht langsamer.

    Google mal nach "p4 barrel shifter". Kommen einige Links dazu. Auf die Gefahr, dass das jetzt zu sehr OT wird, aber intel sollte die P4-Kacke endlich einstampfen...



  • groovemaster schrieb: schrieb:

    Whoa, das hört sich ja ziemlich übel an. Naja, dazu kann ich leider nix sagen, weil ich meinen letzten Pentium '00 zu Grabe getragen hab. Aber normalerweise sollte sich Shiften auf Hardwareebene schon schneller realisieren lassen wie Multiplikationen, oder zumindest nicht langsamer.

    Früher war es in Programmiererkreisen üblich, Ganzzahlmultiplikationen mit 2 bzw. Ganzzahldivisionen durch 2 mit Hilfe der entsprechenden Shift-Operationen durchzuführen, da dies einen kleinen Performancegewinn im Vergleich zur "echten" mathematischen Operation darstellte. Heutzutage ist dieser Performancegewinn nicht mehr vorhanden, da alle
    derzeitigen Architekturen auf solche Operationen optimiert sind. Aus Gründen der Leserlichkeit sollte man also heutzutage nicht mehr auf diese Art der trickreichen Programmierung zurückgreifen. Darüber hinaus optimiert der Compiler in den meisten Fällen solche Dinge automatisch.


Anmelden zum Antworten