Verbleibende bits eines std::uint64_t werden auf ff gesetzt
-
Ich kann es nicht besser beschrieben, hier der Code (Win7 Visual Studio 2012):
std::uint8_t da[] = {0xf9, 0xff, 0xff, 0xff}; std::uint64_t v = 0; for(int b=0; b<4; ++b) { v |= da[b] << (b*8); }0x9f ist das niederwertigste Byte.
Mein Debugger sagt:0x00000000000000f9 0x000000000000fff9 0x0000000000fffff9 0xfffffffffffffff9Waruuuuum warum passiert das ich werde wahnsinnig
Wieso steht da am Ende nicht0x00000000fffffff9
in v?
-
Beim letzten "da[b] << (b*8);" hast du (int)0x00000000fffffff9, was eine negative Zahl ist. Beim impliziten Cast in 64-Bit wird das Vorzeichen übernommen, deshalb das seltsame Resultat.
v |= static_cast<std::::uint64>(da[b]) << (b*8);sollte das Problem beheben.
-
v |= static_caststd::uint64\_t(da[b]) << (b*8);
-
So einfach und doch so nervig... danke sehr

-
Und damit auch klar ist warum das hier passiert...
Bevor C++ mit Zahlen rechnet, tut es sie erstmal "promoten".
Dabei wird aus allem was kleiner ist als eininteinint(signed!). Auch wenn das kleinere Etwasunsignedwar.Nennt sich "integral promotion".
http://en.cppreference.com/w/cpp/language/implicit_cast schrieb:
Prvalues of small integral types (such as
char) may be converted to prvalues of larger integral types (such asint).
In particular, arithmetic operators do not accept types smaller thanintas arguments, and integral
promotions are automatically applied. This conversion always preserves the value.
...(Da stehen dann auch die genauen Regeln wie "promoted" wird.)
Beispiel:
http://ideone.com/wEVZ7t