我最近一直在为稍微修改的Abstract Syntax Notation实现一个专门的解析器。该规范说整数被编码为八位字节数组,这些八位字节数组将被解释为二进制二进制补码整数。
因此,起初我认为将其反序列化为实际 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
,然后我可以通过强制转换将其解释为有符号(二进制补码)整数:
int64_t signed_value = static_cast<int64_t>(value);
但我突然想到,这实际上是依赖于实现定义的行为。 C++ 不保证有符号整数表示为二进制补码。因此,要获得编码整数的实际值作为 C++ int64_t
,我需要实际计算位模式中每个第 N 位的 2^N 的总和,同时考虑符号位。当我知道铸造应该在大多数情况下工作时,这似乎有点愚蠢。
这里有更好的解决方案,既便携又高效?