私は最近、少し変更されたAbstract Syntax Notationに特化したパーサーを実装しています。仕様によると、整数は 2 の補数のバイナリとして解釈されるオクテットの配列としてエンコードされます。
したがって、最初は、これを実際の C++ にシリアル化解除する最善の方法は、int
単純に値 0 から始めて、各オクテットを次のような値で OR することだと思いました。
uint64_t value = 0;
int shift = 0;
std::vector<uint8_t> octets = { /* some values */ };
for (auto it = octets.rbegin(); it != octets.rend(); ++shift, ++it)
{
value |= uint64_t(*it) << (shift * 8);
}
これにより、ビットパターンが に格納されたままになりvalue
、キャストすることで符号付き (2 の補数) 整数として解釈できます。
int64_t signed_value = static_cast<int64_t>(value);
しかし、これは実際には実装定義の動作に依存していることに気づきました。 C++ は、符号付き整数が 2 の補数として表現されることを保証しません。したがって、エンコードされた整数の実際の値を C++ として取得するにはint64_t
、符号ビットを考慮して、ビット パターンの N 番目のビットごとに 2^N の合計を実際に計算する必要があります。ほとんどの場合、キャストが機能するはずだとわかっている場合、これはちょっとばかげているように思えます。
移植可能で効率的な、より良い解決策はありますか?