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
64-bit Endianess Conversion
64-bit Endianess Conversion
Rage - ein "modernes" Rogue-like (C++11, SFML)
- Xin
- nur zu Besuch hier
- Beiträge: 8862
- Registriert: Fr Jul 04, 2008 11:10 pm
- Wohnort: /home/xin
- Kontaktdaten:
Re: 64-bit Endianess Conversion
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.
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.
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.
Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.
Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.
Re: 64-bit Endianess Conversion
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?
LG Glocke
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);
}
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
Rage - ein "modernes" Rogue-like (C++11, SFML)
- Xin
- nur zu Besuch hier
- Beiträge: 8862
- Registriert: Fr Jul 04, 2008 11:10 pm
- Wohnort: /home/xin
- Kontaktdaten:
Re: 64-bit Endianess Conversion
Nein, ich halte auch nix davon.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?
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
}
...
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.
Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.
Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.
Re: 64-bit Endianess Conversion
Okay, das war mir nicht bewusstXin hat geschrieben:Fließkommazahlen werden nicht durch Endianess verändert.

Danke

LG Glocke
Rage - ein "modernes" Rogue-like (C++11, SFML)
Re: 64-bit Endianess Conversion
Stimmt meiner Kenntnis nach nicht.Xin hat geschrieben: Fließkommazahlen werden nicht durch Endianess verändert.
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.
It's as simple as that. And remember, Beethoven wrote his first symphony in C.