Ich versuche, den folgenden Python-Code in C zu übersetzen ++:Auspacken hex-encoded Schwimmer
import struct
import binascii
inputstring = ("0000003F" "0000803F" "AD10753F" "00000080")
num_vals = 4
for i in range(num_vals):
rawhex = inputstring[i*8:(i*8)+8]
# <f for little endian float
val = struct.unpack("<f", binascii.unhexlify(rawhex))[0]
print val
# Output:
# 0.5
# 1.0
# 0.957285702229
# -0.0
So heißt es 32-Bit-Wert des Hex-codierter String, wandelt es in einen Byte-Array mit die unhexlify
Methode und interpretiert es als ein Little-Endian-Float-Wert.
Die fast folgende Werke, aber der Code ist eine Art crappy (und die letzte 00000080
falsch analysiert):
#include <sstream>
#include <iostream>
int main()
{
// The hex-encoded string, and number of values are loaded from a file.
// The num_vals might be wrong, so some basic error checking is needed.
std::string inputstring = "0000003F" "0000803F" "AD10753F" "00000080";
int num_vals = 4;
std::istringstream ss(inputstring);
for(unsigned int i = 0; i < num_vals; ++i)
{
char rawhex[8];
// The ifdef is wrong. It is not the way to detect endianness (it's
// always defined)
#ifdef BIG_ENDIAN
rawhex[6] = ss.get();
rawhex[7] = ss.get();
rawhex[4] = ss.get();
rawhex[5] = ss.get();
rawhex[2] = ss.get();
rawhex[3] = ss.get();
rawhex[0] = ss.get();
rawhex[1] = ss.get();
#else
rawhex[0] = ss.get();
rawhex[1] = ss.get();
rawhex[2] = ss.get();
rawhex[3] = ss.get();
rawhex[4] = ss.get();
rawhex[5] = ss.get();
rawhex[6] = ss.get();
rawhex[7] = ss.get();
#endif
if(ss.good())
{
std::stringstream convert;
convert << std::hex << rawhex;
int32_t val;
convert >> val;
std::cerr << (*(float*)(&val)) << "\n";
}
else
{
std::ostringstream os;
os << "Not enough values in LUT data. Found " << i;
os << ". Expected " << num_vals;
std::cerr << os.str() << std::endl;
throw std::exception();
}
}
}
(kompiliert auf OS X 10.7/gcc-4.2.1, mit einem einfachen g++ blah.cpp
)
Insbesondere würde ich gerne die BIG_ENDIAN
Makro Zeug loswerden, wie ich bin sicher, es gibt eine schönere Möglichkeit, dies zu tun, wie this post diskutiert.
Wenige andere zufällige Details - Ich kann Boost nicht verwenden (zu große Abhängigkeit für das Projekt). Die Zeichenfolge enthält gewöhnlich zwischen 1536 (8 * 3) und 98304 Gleitkommawerten (32 * 3), höchstens 786432 (64 * 3)
(edit2: added anderen Wert, 00000080
== -0.0
)
Ich glaube, Sie (c - 'A') gemeint + 10; angenommen, dass es nur in Großbuchstaben A sein wird –
Auch der Vorteil, es zu tun, Ziffer für Ziffer selbst ist, dass Sie von links nach rechts oder von rechts nach links in Abhängigkeit von Endian-Ness –
@OrgnlDave - das ist, warum 'tolower' ist da. Ja auf der Endian-Ness, obwohl es etwas kniffliger wird (für ein einzelnes Byte Ziffern nicht vertauschen) –