little zu big endian funktioniert nicht

OP Persönliche Seite #3533038
Lesenswert?

Ich muss von little zu big endian auf dem PC konvertieren. Dazu habe ich 
zwei Funktionen:
1
int swapBytes(int dataIn) {
2
  int dataOut;
3
  char *in = (char*)&dataIn, *out = (char*)&dataOut;
4
  for(int i = 0; i < 3; i++) {out[i] = in[3 - i];}
5
  return dataOut;
6
}
7

8
#define swap32(x) \
9
((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >>  8) | (((x) & 0x0000ff00) <<  8) | (((x) & 0x000000ff) << 24))

Die Precompiler-Funktion funktioniert richtig. Aber swapBytes() gibt 
immer 0 zurück. Woran liegt das?
Gast #3533056
Lesenswert?

Maxim S. schrieb:
> Das weiß ich. Diese funktion lässt sich aber nicht auf float anwenden.
> Ich benötige aber Konvertierung sowohl für int als auch für float.

nein das brauchst du kann bestimmt nicht. Float muss nicht gedreht 
werden. Den fehler hatten wir vor kurzen schon mal hier, das jemand 
versucht hat ein float zu drehen - der Fehler lag woanders.
OP Persönliche Seite #3533066
Lesenswert?

Peter II schrieb:
> Maxim S. schrieb:
>> Das weiß ich. Diese funktion lässt sich aber nicht auf float anwenden.
>> Ich benötige aber Konvertierung sowohl für int als auch für float.
>
> nein das brauchst du kann bestimmt nicht. Float muss nicht gedreht
> werden. Den fehler hatten wir vor kurzen schon mal hier, das jemand
> versucht hat ein float zu drehen - der Fehler lag woanders.

Ein float lässt sich so drehen:
1
float swapBytes(float dataIn) {
2
  float dataOut;
3
  char *in = (char*)&dataIn, *out = (char*)&dataOut;
4
  for(int i = 0; i < 3; i++) {out[i] = in[3 - i];}
5
  return dataOut;
6
}

Ein int lässt sich auf diese Weise aber nicht drehen. Dafür kann man 
einen float nicht mit Bitoperationen drehen, da diese hier gar nicht 
anwendbar sind.
Gast #3533070
Lesenswert?

Maxim S. schrieb:
> Peter II schrieb:
>> Maxim S. schrieb:
>>> Das weiß ich. Diese funktion lässt sich aber nicht auf float anwenden.
>>> Ich benötige aber Konvertierung sowohl für int als auch für float.
>>
>> nein das brauchst du kann bestimmt nicht. Float muss nicht gedreht
>> werden. Den fehler hatten wir vor kurzen schon mal hier, das jemand
>> versucht hat ein float zu drehen - der Fehler lag woanders.
>
> Ein float lässt sich so drehen:

ja, aber aus welchen Grund?
Ein float ist auf big und Little endian gleich.
Gast #3533103
Lesenswert?

Johann L. schrieb:
> Maxim S. schrieb:
>> Das weiß ich. Diese funktion lässt sich aber nicht auf float anwenden.
>> Ich benötige aber Konvertierung sowohl für int als auch für float.
>
> Um die Binärdarstellung von float zu bekommen, nimm memcpy. GCC
> optimiert das weg.

wie willst du mit memcpy an eine Binärdarstellung rankommen? memcpy 
kopiert nur Byte von a nach b - es sind immer noch die gleichen bits in 
de gleichen Reihenfolge.
#3533120
Lesenswert?

Falls die Endianess tatsächlich gedreht werden müsste und kein 
MISRA-Checker vorbei kommt, würde ich ganz brutal casten ;-)
1
float a = 87654.321;
2
int b = __builtin_bswap32(*((int *) &a));

bzw. andersherum
1
int a = __builtin_bswap32(irgendeineQuelleMitFalscherEndianess());
2
float b = *((float *) &a));
Persönliche Seite #3533178
Lesenswert?

Peter II schrieb:
> Johann L. schrieb:
>> Maxim S. schrieb:
>>> Das weiß ich. Diese funktion lässt sich aber nicht auf float anwenden.
>>> Ich benötige aber Konvertierung sowohl für int als auch für float.
>>
>> Um die Binärdarstellung von float zu bekommen, nimm memcpy. GCC
>> optimiert das weg.
>
> wie willst du mit memcpy an eine Binärdarstellung rankommen? memcpy
> kopiert nur Byte von a nach b - es sind immer noch die gleichen bits in
> de gleichen Reihenfolge.

Genau darum geht es.  Wenn man ein float in eine Funktion steckt, die 
ein int erwartet, gibt's eine implizite Umwandlung nach int.  Das will 
der TO hier offenbar nicht.
OP Persönliche Seite #3534458
Lesenswert?

<= schrieb:
> Maxim S. schrieb:
>> for(int i = 0; i < 3; i++)
>
> for(int i = 0; i <= 3; i++)

Tatsächlich, da war ein Fehler. Da die floats aber alle nicht größer als 
1.0 sind, hat das trotzdem noch funktioniert. ;) Danke.

Peter II schrieb:
> Johann L. schrieb:
>> Das will
>> der TO hier offenbar nicht.
> er will die Byte von einen float drehen, das alleine ist schon
> merkwürdig.

Ich muss die Bytes von floats tatsächlich drehen, weil das 
VTK-Dateiformat das so haben möchte. Mittlerweile funktioniert es auch 
und zwar so:
1
float swapBytes(float dataIn) {
2
  float dataOut;
3
  char *in = (char*)&dataIn, *out = (char*)&dataOut;
4
  for(int i = 0; i < 3; i++) {out[i] = in[3 - i];}
5
  return dataOut;
6
}

Die gleiche Funktion für int funktioniert aber nicht. Da benutze ich 
dann die Bitoperatoren.
Gast #3535884
Lesenswert?

<= schrieb:
> Maxim S. schrieb:
>> for(int i = 0; i < 3; i++)
>
> for(int i = 0; i <= 3; i++)

Da würde ich eher die übliche Schweibweise bevorzugen:
1
for(int i = 0; i < 4; i++)

Simon K. schrieb:
> char ist nicht zwangsläufig 1 Byte groß...

Doch, ist es.

> Und float nicht zwangsläufig 32 Bit.

Statt 4 könnte man besser sizeof(float) nehmen.
Gast #3536358
Lesenswert?

Kaj schrieb:
> Gibt genug Plattformen wo char größer als 1 Byte ist.

Dann sind die kaputt. Aus ISO C:

******************************************
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.
******************************************
#3538451
Lesenswert?

Ich denke damit ist gemeint, dass es Prozessoren gibt, die einfach von 
ihrer Architektur her niemals weniger bearbeiten können als 16 (oder 32 
etc.) Bits auf einmal. Ist halt nicht jeder ein x86 und hat AL, AX, EAX 
und wie sie alle heißen.

Trifft meines Wissens nach zum Beispiel auf diverse DSP zu.

Hat es einen besonderen Sinn, so zu tun als ob ein char zwangsläufig aus 
einem Byte besteht? Ein Byte besteht nun mal in aller Regel aus 8 Bits - 
wir sind hier nicht auf einer PDP ;-)
Gast #3538633
Lesenswert?

Mark Brandis schrieb:
> Ich denke damit ist gemeint, dass es Prozessoren gibt, die einfach von
> ihrer Architektur her niemals weniger bearbeiten können als 16 (oder 32
> etc.) Bits auf einmal. Ist halt nicht jeder ein x86 und hat AL, AX, EAX
> und wie sie alle heißen.
>
> Trifft meines Wissens nach zum Beispiel auf diverse DSP zu.

Genau. Die gibt es auch z.B. 24 Bits.

> Hat es einen besonderen Sinn, so zu tun als ob ein char zwangsläufig aus
> einem Byte besteht?

Man "tut" nicht "so", sondern definert es. Ein Mathematiker tut ja auch 
nicht so, als sei + das Zeichen für die Addition, sondern bestimmt halt, 
daß es so ist.

> Ein Byte besteht nun mal in aller Regel aus 8 Bits - wir sind hier nicht
> auf einer PDP ;-)

Ein Byte besteht in der Regel aus der kleinsten adressierbaren Einheit, 
und die ist gerade auf besagten DSPs dann eben nicht 8 Bit groß.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren