• 23.05.2025, 06:53
  • Registrieren
  • Anmelden
  • Sie sind nicht angemeldet.

 

Lieber Besucher, herzlich willkommen bei: Aqua Computer Forum. Falls dies Ihr erster Besuch auf dieser Seite ist, lesen Sie sich bitte die Hilfe durch. Dort wird Ihnen die Bedienung dieser Seite näher erläutert. Darüber hinaus sollten Sie sich registrieren, um alle Funktionen dieser Seite nutzen zu können. Benutzen Sie das Registrierungsformular, um sich zu registrieren oder informieren Sie sich ausführlich über den Registrierungsvorgang. Falls Sie sich bereits zu einem früheren Zeitpunkt registriert haben, können Sie sich hier anmelden.

C++: Int to char und umgekehrt

Montag, 21. April 2003, 19:12

Sers Jungs!

Ich versuch mich grad a bisserl mit der Netzwerkprogrammierung, und dabei stoße ich auf folgendes Problem: Ich kann nur chars über Netz verschicken.

Meine Frage: Wie kann ich ein Integer in ein char umwandeln und umgekehrt?

Ich programmiere mit M$-Visual Studio 6.0

Danke Cu

Re: C++: Int to char und umgekehrt

Montag, 21. April 2003, 19:36

sowohl int als auch char speichern zalen, wo is da das problem?
solang du nur werte zw 0 und 255 benutzt kanns einem char jederzeit n int wert zuweisen und umgekehrt isset eh kein prob

btw: wie kommst drauf dasse nur chars verschicken kanns? spricht wirklich nix dagegen die datenpakete n bisserl grölßer zu gestalten als 1 byte und andere variablen oder meinetwegen auch komplexe datenstrukturen zu verschicken... ::)

LiquidAcid

unregistriert

Re: C++: Int to char und umgekehrt

Montag, 21. April 2003, 19:44

Das Problem ist, dass auf einer x86 Architektur die Bytegrößte eines normalen Integers (und der ist eigentlich ein: signed long int) 4 ist, also 32 Bit.
Ein char ist allerdings nur 1 Byte groß (8 Bit).

Mit expliziten Typecasts von signed long int zu char kommt man zwar weiter, aber die übrigen 3 Bytes bleiben dann auf der Strecke. Wenn du wirklich nur chars übertragen kannst, dann wirst du wohl nicht um 4 Übertragungen von je 1 Byte (also char) herumkommen.
Aber wie rippchen ja schon gesagt hat, ich würde mal gucken ob das nicht auch anders geht.

cya
liquid

PS:
[code]
void split_int_into_char(signed long int the_int, char* the_chars)
{
char* ptr = &the_int; // guck mal welcher typecast da passt

// kein loop wegen dem overhead
the_chars[0] = ptr[0];
the_chars[1] = ptr[1];
the_chars[2] = ptr[2];
the_chars[3] = ptr[3];
}

EDIT: Da die Datentypen nicht verwandt sind, würde ich die Holzhammermethode, also reinterpret_cast benutzen.

Re: C++: Int to char und umgekehrt

Montag, 21. April 2003, 20:34

Hallo,
mir würde spontan sowas dazu einfallen,
CHR --> INT

int Zahl;
unsigned char a,b,c,d;
// A = msb C = LSB

Zahl = ( (a<<24)&#124;((b<<16)&#124;(c<<8)&#124;(d) );



INT --> CHR

int Zahl;
unsigned char a,b,c,d;
// A = msb C = LSB

a= (zahl>>24);
b= (zahl<<8)&(zahl>>24); // erst nach lins schieben um die MSB zu löschen dann nach rechts um in 8 bit zu kommen
c= ..
d...


-------------------------------------------------
in ANSI C funtioniert das , da C ja eine untermenge von C++ ist sollte es auch in C++ funkt. ,.. das einzige problem ist das diese routien von der implementation des Compilers abhängen und unter umständen nicht auf eíner 64bit maschiene oä. laufen.


MfG
Sebastian

Re: C++: Int to char und umgekehrt

Montag, 21. April 2003, 20:41

Hi,

ich würde es ein bisschen wie LiquidAcid machen, nur schneller.

Casting von int nach char:

int iInteger = 0;
char* pCharToInteger = &iInteger;


Casting von char nach int:

char cCharInteger[sizeof(int)];
int* pInteger = cCharInteger;


Natürlich sollte beim Senden die Länge des Integers berücksichtigt werden. Somit sind für ein Int auf jeden Fall 4 chars zu senden.

mfg,
cobra224

LiquidAcid

unregistriert

Re: C++: Int to char und umgekehrt

Montag, 21. April 2003, 20:56

Zitat von »Sebastian«

Hallo,
mir würde spontan sowas dazu einfallen,
CHR --> INT

int Zahl;
unsigned char a,b,c,d;
// A = msb C = LSB

Zahl = ( (a<<24)&#124;((b<<16)&#124;(c<<8)&#124;(d) );



INT --> CHR

int Zahl;
unsigned char a,b,c,d;
// A = msb C = LSB

a= (zahl>>24);
b= (zahl<<8)&(zahl>>24); // erst nach lins schieben um die MSB zu löschen dann nach rechts um in 8 bit zu kommen
c= ..
d...


-------------------------------------------------
in ANSI C funtioniert das , da C ja eine untermenge von C++ ist sollte es auch in C++ funkt. ,.. das einzige problem ist das diese routien von der implementation des Compilers abhängen und unter umständen nicht auf eíner 64bit maschiene oä. laufen.


MfG
Sebastian

Ist das nicht ein wenig zu viel Bitshifting? Nichts gehen die Methode, aber sie ist recht ineffizient.
Ich finde sowieso das diese Konvertierung nicht die Lösung für das Problem sein sollte. Versuch lieber irgendeine Möglichkeit zu finden, die Datenmenge zu spezifizieren, sonst musste wirklich jeden Datentyp erst zerlegen vorm Senden.

cya
liquid

Re: C++: Int to char und umgekehrt

Montag, 21. April 2003, 21:13

eigentlich müsste das je nach maschiene höchst effizient sein, da der compiler die einzelnen shifings direkt in 1ASM maschinenzyklen umrechnet und somit keine poinertoperationen und speichzugriffe mehr erfolgen. sozusagen ist das ja nur die verschönte schreibweise um bits zu maskieren /kopieren oder löschen zu können. diese schreibweise ist sehr an die HW angelent und braucht keinesfalls 24zyklen (zahl>>24) für diese operation, sondern nur 1Takt oder ein paar mehr ja nach ALU.

Re: C++: Int to char und umgekehrt

Montag, 21. April 2003, 21:36

Was nützt den das Anlegen eines neuen Char-Feldes?
Nach meinem Erinnerungsvermögen muß dem Win32API od. MFC Befehl eh ein Char-Pointer übergeben werden.
Ausserdem liegt der Vorteil im Casting darin, daß du nicht eine weitere Variable mit Werten anlegen mußt.
Desweitern dauert das Shiften auf eine neue Var länger als nur einen Pointer zu verweisen. Es wird nur die Adresse des Char-Feldes dem Int zugewiesen und das macht der Compiler. ;)

mfg,
cobra224

LiquidAcid

unregistriert

Re: C++: Int to char und umgekehrt

Montag, 21. April 2003, 21:43

Zitat von »cobra224«

Hi,

ich würde es ein bisschen wie LiquidAcid machen, nur schneller.

Casting von int nach char:

int iInteger = 0;
char* pCharToInteger = &iInteger;


Casting von char nach int:

char cCharInteger[sizeof(int)];
int* pInteger = cCharInteger;


Natürlich sollte beim Senden die Länge des Integers berücksichtigt werden. Somit sind für ein Int auf jeden Fall 4 chars zu senden.

mfg,
cobra224


Ich glaube dennoch, dass cobra Code am schnellsten laufen wird, besonders wenn man gegen die C++ Regeln C-Style-Cast benutzt, die sind ja ungeprüft und erzeugen keinen zusätzlichen Code.
Das einzige was hierbei geschieht sind Allokierung von 32Bit für den Pointer und eine Zuweisung.
Bei deinem int_to_char haben wir auch eine Allokation von 32Bit (4 mal einen Char), aber gleich 4 Zuweisungen und mehrere Bitshifts.

Korrigier mich wenn ich da falsch liege, aber wenn die Daten richtig bereitliegen, dann ist cobras Code doch optimal. Zwar ein wenig unschöne Pointergeschichte, aber darüber kann man ja wohl hinwegsehen.

cya
liquid

LiquidAcid

unregistriert

Re: C++: Int to char und umgekehrt

Montag, 21. April 2003, 21:44

Zitat von »cobra224«

Was nützt den das Anlegen eines neuen Char-Feldes?
Nach meinem Erinnerungsvermögen muß dem Win32API od. MFC Befehl eh ein Char-Pointer übergeben werden.
Ausserdem liegt der Vorteil im Casting darin, daß du nicht eine weitere Variable mit Werten anlegen mußt.
Desweitern dauert das Shiften auf eine neue Var länger als nur einen Pointer zu verweisen. Es wird nur die Adresse des Char-Feldes dem Int zugewiesen und das macht der Compiler. ;)

mfg,
cobra224


Full ACK, besonders wenn die Zuweisung ungeprüft stattfindet.

EDIT: -> C Wars - Return of the wild pointer ;D

EDIT2: Jemand eine Ahnung ab welcher Optimierungsstufe Divisionen mit konstanten Variablentypen in Multiplikationen mit dem reziproken Wert umgewandelt werden?
Also wenn ich jetzt folgendes schreibe

Quellcode

1
2
#define PI 3.14159
float val = bla_bla / PI;


Dann wär man ja schön doof, wenn man die Division da so einfach stehen lassen würde. Das verbrät ja Takte en masse.

Also wann fudelt der Compiler das um?

Re: C++: Int to char und umgekehrt

Donnerstag, 24. April 2003, 22:33

Zitat von »LiquidAcid«



Full ACK, besonders wenn die Zuweisung ungeprüft stattfindet.

EDIT: -> C Wars - Return of the wild pointer ;D

EDIT2: Jemand eine Ahnung ab welcher Optimierungsstufe Divisionen mit konstanten Variablentypen in Multiplikationen mit dem reziproken Wert umgewandelt werden?
Also wenn ich jetzt folgendes schreibe

Quellcode

1
2
#define PI 3.14159
float val = bla_bla / PI;


Dann wär man ja schön doof, wenn man die Division da so einfach stehen lassen würde. Das verbrät ja Takte en masse.

Also wann fudelt der Compiler das um?


Ich vermute, daß der Compiler beim Übersetzen dies direkt optimiert. Hängt wahrscheinlich von der Optimierungseinstellung des Compilers ab.
Beim MS Studio ist es eine Grundeinstellung das Konstanten in Verbindung mit Operatoren optimal compiliert werden.
Aber 100% bin ich mir nicht sicher.

mfg,
cobra224

EDIT: -> C Wars - The NULL-Pointer strikes back ;)

LiquidAcid

unregistriert

Re: C++: Int to char und umgekehrt

Donnerstag, 24. April 2003, 23:18

Zitat von »cobra224«



Ich vermute, daß der Compiler beim Übersetzen dies direkt optimiert. Hängt wahrscheinlich von der Optimierungseinstellung des Compilers ab.
Beim MS Studio ist es eine Grundeinstellung das Konstanten in Verbindung mit Operatoren optimal compiliert werden.
Aber 100% bin ich mir nicht sicher.

mfg,
cobra224

EDIT: -> C Wars - The NULL-Pointer strikes back ;)


Na dann muss ich mal wohl den kompilierten Code auseinandernehmen und mir das ASM angucken. Vielleicht werd ich draus schlau... ::) ;)

hus

Senior Member

Re: C++: Int to char und umgekehrt

Montag, 28. April 2003, 13:38

Da es ursprünglich um Netzwerkprogrammierung ging, gibt es noch einen weiteren Aspekt: die richtige Sortierung der Bytes, auch genannt "byte order". Um korrekte Übertragung sicherzustellen, müssen Integer-Werte vor dem Versand mit der Funktion "hton" ("host to network byte order") und nach dem Empfang mit "ntoh" ("network to host") umgestellt werden. Für kurze bzw. lange ints ist ein "s" bzw. "l" anzuhängen.

Die Hilfe-Funktion sollte wissen, wann genau das notwendig ist und welches jeweils die richtige Funktion ist.
Real stupidity beats artificial intelligence every time. T. Pratchett, "Hogfather"

LiquidAcid

unregistriert

Re: C++: Int to char und umgekehrt

Montag, 28. April 2003, 14:47

@hus: Du hast nicht zufällig auch Ahnung von i386/x86 Assembler? Im speziellen vielleicht auch AT&T Assembler Style? Nur so eine Idee, ich bräuchte da nämlich ein wenig Hilfe.

cya
liquid

hus

Senior Member

Re: C++: Int to char und umgekehrt

Montag, 28. April 2003, 15:52

@LiquidAcid: Hmmm... Für den Apple ][ brauchte ich damals keinen Assembler, die Opcodes hatte ich fast alle im Kopf... x86 habe ich das letzte Mal in Assembler programmiert, als der i386 ganz neu war. Benutzt habe ich dafür den Borland TASM. Heutzutage programmiere ich zwar wieder Intel-kompatible Prozessoren, aber nur Microcontroller aus der 8051-Familie...
Ich werde Dir also vielleicht Tips geben können, aber keine Spezialfragen beantworten.
Real stupidity beats artificial intelligence every time. T. Pratchett, "Hogfather"

LiquidAcid

unregistriert

Re: C++: Int to char und umgekehrt

Montag, 28. April 2003, 17:01

Ich weiß auch nicht genau, ob es überhaupt eine Spezialfrage ist. Jedenfalls geht es um folgendes. Ich hab versucht Intel Assembler Code auf AT&T Assembler zu "übersetzen", damit ich diesen im GCC verwenden kann. Allerdings funzt das ganze überhaupt nicht.
Problem ist, dass er mir beim Linken meldet "undefined reference to valueX".

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
void special::printMHz()
{
      DWORD value0 = 0;
      DWORD value1 = 0;
      DWORD value2 = 0;
      DWORD value3 = 0;

      __asm("rdtsc");
      __asm("movl value0, %eax");
      __asm("movl value1, %edx");

      _sleep(1000);

      __asm("rdtsc");
      __asm("movl value2, %eax");
      __asm("movl value3, %edx");

      value0 = value2 - value0;
      value1 = value3 - value1;
      
      std::cout << "CPU clock is: " << double(value0 + (value1 * 4294967296)) * 0.000001;
}


Ich wundere mich nur, weil in der Doku steht, dass im Assembler Code die gleichen C-Variablennamen gelten, wie im C-Code. Also warum kann er dann value0, value1, value2 und value3 net finden? Irgendwie hab ich glaubich den Syntax nicht so richtig.

cya
liquid