Hi! Ich hab ein Programmiertechnisches Problem! Wie bekomme ich aus einem char array einen Long Wert? Mein Vorschlag: char c[4]; long l; l=0; l=c[0]; l=l+(c[1]*0x100); l=l+(c[2]*0x10000); l=l+(c[3]*0x1000000); Nur leider funkrioniert das nicht so ganz.. Ich könnte auch einen anderen variablen Typ anstatt char nehmen! Muss nur genau ein Byte groß sein! (Ich hab ne x86_64 architektur, macht das einen unterschied?) mfg Jan
On Thursday 19 August 2004 16:59, Jan Hendrik Berlin wrote:
Ich hab ein Programmiertechnisches Problem! Wie bekomme ich aus einem char array einen Long Wert?
Mein Vorschlag:
char c[4]; long l;
l=0; l=c[0]; l=l+(c[1]*0x100); l=l+(c[2]*0x10000); l=l+(c[3]*0x1000000);
Nur leider funkrioniert das nicht so ganz.. Ich könnte auch einen anderen variablen Typ anstatt char nehmen! Muss nur genau ein Byte groß sein! (Ich hab ne x86_64 architektur, macht das einen unterschied?)
Du bist Dir hoffentlich klar darüber, daß Du Dir alle möglichen Probleme mit
Byte-Order und Wortbreite der verwendeten Architektur einhandelst?!
Tu' solche Sachen nur, wenn Du _sehr_ genau weißt, was Du tust - am besten
erklär' doch mal, was Du damit eigentlich vorhast.
Im übrigen hast Du zwar das Horner-Schema richtig angewendet, aber statt einer
teuren Multiplikation sollte man hier besser einen Links-Shift um 8 Stellen
verwenden:
l=c[0];
l <<= 8;
l += c[1];
l << = 8;
...
Auf die Reihenfolge habe ich hier jetzt absichtlich nicht geachtet, denn das
ist wirklich architekturabhängig - damit machst Du Dein Programm im höchsten
Maß unportabel.
CU
--
Stefan Hundhammer
Stefan Hundhammer schrieb:
On Thursday 19 August 2004 16:59, Jan Hendrik Berlin wrote: [...]
l=0; l=c[0]; l=l+(c[1]*0x100); l=l+(c[2]*0x10000); l=l+(c[3]*0x1000000); [...] Im übrigen hast Du zwar das Horner-Schema richtig angewendet,
Hat er eben nicht!
aber statt einer teuren Multiplikation sollte man hier besser einen Links-Shift um 8 Stellen verwenden:
Das macht eigentlich jeder Compiler, der sein Geld wert ist, von sich aus, wenn er eine Multiplikation mit einer konstanten Zweierpotenz sieht.
Auf die Reihenfolge habe ich hier jetzt absichtlich nicht geachtet, denn das ist wirklich architekturabhängig - damit machst Du Dein Programm im höchsten Maß unportabel.
Oder gerade erst portabel - wenn nämlich die Bytereihenfolge extern vorgegeben und unabhängig von der Maschinenarchitektur ist. -- Tilman Schmidt t.schmidt@phoenixsoftware.de Phoenix Software GmbH Tel. +49 228 97199 0 Adolf-Hombitzer-Str. 12 Fax +49 228 97199 99 53227 Bonn, Germany http://www.phoenixsoftware.de
Jan Hendrik Berlin schrieb:
Ich hab ein Programmiertechnisches Problem! Wie bekomme ich aus einem char array einen Long Wert?
Das kommt darauf an. (TM) Was willst Du denn mit der Konversion erreichen? Was steht in dem Array, und in welchem Zusammenhang soll der gebildete long-Wert damit stehen?
Mein Vorschlag:
char c[4]; long l;
l=0; l=c[0]; l=l+(c[1]*0x100); l=l+(c[2]*0x10000); l=l+(c[3]*0x1000000);
Das sieht aus, als ob Du das Array als die vier Bytes eines low endian 32 bit integer interpretieren wolltest. Nur leider ist das (a) recht ineffizient und behandelt (b) die sign extension falsch.
Nur leider funkrioniert das nicht so ganz..
Was immer das heißen mag.
Ich könnte auch einen anderen variablen Typ anstatt char nehmen! Muss nur genau ein Byte groß sein!
Wenn Du unsigned char c[4]; unsigned long l; nimmst, dürfte obiges funktionieren. Etwas effizienter wäre das Horner-Schema: l = c[3]; l = 0x100 * l + c[2]; l = 0x100 * l + c[1]; l = 0x100 * l + c[0]; -- Tilman Schmidt t.schmidt@phoenixsoftware.de Phoenix Software GmbH Tel. +49 228 97199 0 Adolf-Hombitzer-Str. 12 Fax +49 228 97199 99 53227 Bonn, Germany http://www.phoenixsoftware.de
On Thu, 2004-08-19 at 16:59, Jan Hendrik Berlin wrote:
Hi!
Muss nur genau ein Byte groß sein! In modernem POSIX-C gibt es dazu die Datentypen int8_t und uint8_t (Vgl. /usr/include/stdint.h und /usr/include/inttypes.h)
Wenn es auf der Gegenseite ein 32 Bit-Int sein soll, solltest Du statt "int" oder "long" (sind architekturabhängig) die Datentypen int32_t oder uint32_t in Erwägung ziehen.
(Ich hab ne x86_64 architektur, macht das einen unterschied?) Keine Ahnung worauf Du raus willst. Ja, im Allgemeinen ist Einiges daran reichlich unportabel.
[Schau Dir mal die Implementierungen der Network/Host-Byteorder Konversionsroutinen (htons, htonl etc.) auf verschiedenen OSen und Architekturen an. Sie sind Deiner Problematik nicht unähnlich.] Wenn Du Portabilität zu ia32-Linux meinst: Nein, in diesem Fall sind Probleme unwahrscheinlich. Wenn Du Portabilität zu VAXen, Microcontrollern und Mainframes meinst: Teufelsküche! :-) Ralf
OK, Ok! Also der long Wert kann ja den Wert 0xffffffff haben! jedes ff ist ein Teil meines char arrays! obwohl ich das eventuell besser mit einem int array machen sollte! Es geht darum einem USB Chip einen Wert rüber zu schicken! Der muss halt long sein! Mit einem array jeglicher Art (die Art der Variablen muss halt ein Byte haben!) geht das halt wesentlich einfacher! mfg Jan
Jan Hendrik Berlin wrote: [...]
Es geht darum einem USB Chip einen Wert rüber zu schicken! Der muss halt long sein! Mit einem array jeglicher Art (die Art der Variablen muss halt ein Byte haben!) geht das halt wesentlich einfacher!
Hi,
also ohne jetzt genauer drueber nachgedacht zu haben:
long v;
write( fd, &v, sizeof( v));
sollte doch funktionieren, oder vielleicht das:
uint32_t v;
for (int i = 0; i < 4; ++i) {
bytewrite( static_cast
Sebastian Huber schrieb:
Jan Hendrik Berlin wrote: [...]
Es geht darum einem USB Chip einen Wert rüber zu schicken! Der muss halt long sein! Mit einem array jeglicher Art (die Art der Variablen muss halt ein Byte haben!) geht das halt wesentlich einfacher!
Wichtiger als Einfachheit ist Korrektheit. Wie der USB-Chip diesen long-Wert erwartet, ob byteweise binär und wenn ja in welcher Reihenfolge, steht in seiner Spezifikation, und genau so muss man das dann auch machen. Es nützt nichts, wenn man low endian schickt weil das einfacher ist, der Chip es aber high endian erwartet - dann funktioniert es eben nicht.
also ohne jetzt genauer drueber nachgedacht zu haben:
long v; write( fd, &v, sizeof( v));
sollte doch funktionieren, oder vielleicht das:
uint32_t v; for (int i = 0; i < 4; ++i) { bytewrite( static_cast
( &v) + i); }
Brr, nee, gerade wenn am anderen Ende ein Stück Hardware sitzt, sollte man die Bytes gezielt in der Reihenfolge senden, in der dieses sie erwartet, und nicht einfach so wie die eigene CPU-Architektur sie zufällig abgelegt hat. Genau das meinte ich mit: [Damit wird das Programm]
gerade erst portabel - wenn nämlich die Bytereihenfolge extern vorgegeben und unabhängig von der Maschinenarchitektur ist.
-- Tilman Schmidt t.schmidt@phoenixsoftware.de Phoenix Software GmbH Tel. +49 228 97199 0 Adolf-Hombitzer-Str. 12 Fax +49 228 97199 99 53227 Bonn, Germany http://www.phoenixsoftware.de
hmm, mir gehts doch gar nicht um den USB-Chip! Das lasst mal meine Sorge sein! Ich hab einen long, und der maximalwert ist 0xffffffff. und ff steht immer für ein Port! Auf jedem Port sind 8 IO-Pins! und das entspricht ja einem Byte! Ich möchte nun ein Stück Code haben, was mir aus einem array, was vier einzelne Bytes enthält, diesen long Wert zusammensetzt! Und ich habs schon probiert, aber ich hab da so meine Problemchen mit! Mein Code funktioniert nicht! mfg jan
Jan Hendrik Berlin schrieb:
[...] Ich möchte nun ein Stück Code haben, was mir aus einem array, was vier einzelne Bytes enthält, diesen long Wert zusammensetzt! Und ich habs schon probiert, aber ich hab da so meine Problemchen mit! Mein Code funktioniert nicht!
Endianess- und sonstige Problemchen außer Acht lassend: char c[4]; long l; l = *(long*)c; -- Gruß, Alex
Jan Hendrik Berlin wrote: [...]
Ich hab einen long, und der maximalwert ist 0xffffffff. und ff steht immer für ein Port! Auf jedem Port sind 8 IO-Pins! und das entspricht ja einem Byte!
Ich möchte nun ein Stück Code haben, was mir aus einem array, was vier einzelne Bytes enthält, diesen long Wert zusammensetzt! Und ich habs schon probiert, aber ich hab da so meine Problemchen mit! Mein Code funktioniert nicht!
uint32_t v = 0x12345678; uint8_t b [4]; b [0] = v; b [1] = v / 256; b [2] = v / 65536; b [3] = v / 16777216; Damit sollte es doch gehen, und es sieht ganz portabel aus. Ciao Sebastian
Sebastian Huber wrote:
Jan Hendrik Berlin wrote: [...]
Ich hab einen long, und der maximalwert ist 0xffffffff. und ff steht immer für ein Port! Auf jedem Port sind 8 IO-Pins! und das entspricht ja einem Byte!
Ich möchte nun ein Stück Code haben, was mir aus einem array, was vier einzelne Bytes enthält, diesen long Wert zusammensetzt! Und ich habs schon probiert, aber ich hab da so meine Problemchen mit! Mein Code funktioniert nicht!
uint32_t v = 0x12345678; uint8_t b [4]; b [0] = v; b [1] = v / 256; b [2] = v / 65536; b [3] = v / 16777216;
Damit sollte es doch gehen, und es sieht ganz portabel aus.
Gut lesen sollte man schon koennen: uint32_t v = 0; uint8_t b [4]; v += b [0]; v += b [1] * 256; v += b [2] * 65536; v += b [4] * 16777216; Ciao Sebastian
uint32_t v = 0; uint8_t b [4]; v += b [0]; v += b [1] * 256; v += b [2] * 65536; v += b [4] * 16777216;
Das gefällt mir! macht nur noch bissl ärger!
Mein Quelltext:
# include
Hi Jan! Jan Hendrik Berlin schrieb am 22.08.2004 21:42 :
Ich denke, ich muss noch ne header einbinden oder? iostream reicht da wohl nicht! Was will der denn für uint haben?
Lies doch mal die Antwort von Ralf Corsepius genau durch. Er hat dir die nötigen Antworten längst gegeben. Gruß, Michael
Jan Hendrik Berlin schrieb:
hmm, mir gehts doch gar nicht um den USB-Chip!
Das lasst mal meine Sorge sein!
Ich hab einen long, und der maximalwert ist 0xffffffff. und ff steht immer für ein Port! Auf jedem Port sind 8 IO-Pins! und das entspricht ja einem Byte!
Sorry, ich dachte, die Software sollte real eingesetzt werden. Ich wusste nicht, dass es um ein Spielprojekt geht. Da ist die Situation natürlich anders.
Ich möchte nun ein Stück Code haben, was mir aus einem array, was vier einzelne Bytes enthält, diesen long Wert zusammensetzt! Und ich habs schon probiert, aber ich hab da so meine Problemchen mit! Mein Code funktioniert nicht!
Das habe ich schon am 19.08.2004 18:26 beantwortet und sowohl den vermutlichen Grund als auch mögliche Abhilfe genannt. "Vermutlich" und "möglich" deshalb, weil Du leider verschweigst, worin sich denn das Nichtfunktionieren Deines Codes äußert, so dass es durchaus auch noch andere Probleme geben könnte, die da eine Rolle spielen und die ich von hier aus nicht sehen kann. (Meine Kristallkugel ist leider gerade beim Polieren.) -- Tilman Schmidt t.schmidt@phoenixsoftware.de Phoenix Software GmbH Tel. +49 228 97199 0 Adolf-Hombitzer-Str. 12 Fax +49 228 97199 99 53227 Bonn, Germany http://www.phoenixsoftware.de
participants (7)
-
Alexander Veit
-
Jan Hendrik Berlin
-
Michael Wenger
-
Ralf Corsepius
-
Sebastian Huber
-
Stefan Hundhammer
-
Tilman Schmidt