Seite 1 von 1
64-bit Endianess Conversion
Verfasst: Fr Feb 07, 2014 5:20 pm
von Glocke
Hi,
ich habe für meine Netzwerk-Library [1] eine
BinaryStream-Klasse, die Daten beim Einfügen in BigEndian konvertiert. Dabei verwende ich
htons etc. Allerdings habe ich für 64-Bit-Typen (
long long oder
double) nichts derartiges gefunden - zumindest nicht in C++11 Standard. Notwendig sollte dies eigentlich schon sein (siehe Aufteilung von Mantisse und Exponenten bei double). Gibt es da schlicht und ergreifend einfach (noch) nichts im aktuellen Standard? Wie kann ich die Konvertierung am schnellsten durchführen?
LG Glocke
[1]
https://github.com/cgloeckner/netLib
Re: 64-bit Endianess Conversion
Verfasst: Fr Feb 07, 2014 5:49 pm
von Xin
Grundsätzlich müsstest Du lediglich aus dem long long int zwei 32 Bit ints machen, z.B. durch ein Union.
Du hast ein vorderes und ein hinteres Int. Die beiden musst du zum einen vertauschen und dann auf beide hoch htons anwenden.
So sollte es gehen.
Re: 64-bit Endianess Conversion
Verfasst: Fr Feb 07, 2014 5:55 pm
von Glocke
Also ich habe folgende Methode zum schreiben (lesen analog):
Code: Alles auswählen
template <typename T>
void BinaryStream::write(T const data) {
std::size_t bytes = sizeof(T);
T converted;
// convert from host byte order to big endian
switch (bytes) {
case 1: // 8 bit, nothing to do
converted = data;
break;
case 2: // 16 bit
converted = htons(data);
break;
case 4: // 32 bit
converted = htonl(data);
break;
//case 8: // 64 bit, nothing known to me
// break;
default:
return;
}
// append to buffer
this->append(&converted, bytes);
}
Dabei unterscheide ich anhand sizeof(T) nach der Anzahl der Bytes für den jeweiligen Typ (Zeiger fange ich hier nicht ab - die gehören hier nicht rein). Prinzipiell will ich nur Primitivdaten einfügen, d.h. keine structs o.Ä. - Vermutlich müsste ich dazu für jeden einzelnen Typ die Methode überladen (so wie es bei SFML gemacht wurde). Das wollte ich vermeiden ^^
Joa also bräuchte ich eine Unterscheidung ob es ein long-long oder ein double ist, da ich beide ja anders konvertiere. D.h. mein Ansatz ist nicht geeignet, oder?
LG Glocke
Re: 64-bit Endianess Conversion
Verfasst: Fr Feb 07, 2014 6:02 pm
von Xin
Glocke hat geschrieben:Also ich habe folgende Methode zum schreiben (lesen analog):
...
Dabei unterscheide ich anhand sizeof(T) nach der Anzahl der Bytes für den jeweiligen Typ (Zeiger fange ich hier nicht ab - die gehören hier nicht rein). Prinzipiell will ich nur Primitivdaten einfügen, d.h. keine structs o.Ä. - Vermutlich müsste ich dazu für jeden einzelnen Typ die Methode überladen (so wie es bei SFML gemacht wurde). Das wollte ich vermeiden ^^
Joa also bräuchte ich eine Unterscheidung ob es ein long-long oder ein double ist, da ich beide ja anders konvertiere. D.h. mein Ansatz ist nicht geeignet, oder?
Nein, ich halte auch nix davon.
Code: Alles auswählen
void BinaryStream::write(char const * data, unsigned int size )
{ /* ... Daten schreiben ... */ }
template <typename T>
void BinaryStream::write(T const data);
template <>
inline void BinaryStream::write(long long int const data)
{
char array[8];
...
write( data, 8 ); // die eigentliche Funktion
}
template <>
inline void BinaryStream::write(float const data)
{
...
write( static_cast< char * >( &data), 4 ); // die eigentliche Funktion
}
...
Fließkommazahlen werden nicht durch Endianess verändert.
Re: 64-bit Endianess Conversion
Verfasst: Fr Feb 07, 2014 6:09 pm
von Glocke
Xin hat geschrieben:Fließkommazahlen werden nicht durch Endianess verändert.
Okay, das war mir nicht bewusst

Dann werde ich das Template für long long überladen (wie ich es auch bei std::string gemacht habe ^^)
Danke
LG Glocke
Re: 64-bit Endianess Conversion
Verfasst: Fr Feb 07, 2014 6:34 pm
von mfro
Xin hat geschrieben:
Fließkommazahlen werden nicht durch Endianess verändert.
Stimmt meiner Kenntnis nach nicht.
Zumindest die "großen" Plattformen, die ich als Big-Endian kenne (Sparc und Power) speichern Fließkommazahlen ebenso als Big-Endian ab.
Fließkommazahlen müssen also, wenn sie auf einem Little-Endian System eingelesen werden, genauso wie ints "rumgedreht" werden. Gerüchteweise soll es ARM-Prozessoren geben, die Integer Little-Endian und Fließkommazahlen Big-Endian ablegen.
Was es allerdings meiner Kenntnis nach nicht gibt, ist die Definition einer "Network Byte Order" (also ein standardisiertes Übertragungsformat). Im Gegensatz zu den Integer-Formaten definiert die IEEE nicht, was "richtig" ist.