c – 二进制补码表示
发布时间:2020-12-16 07:05:08 所属栏目:百科 来源:网络整理
导读:我最近一直在为稍微修改过的 Abstract Syntax Notation实现一个专门的解析器.规范说整数被编码为一个八位字节数组,它被解释为二进制二进制补码整数. 所以,起初我认为将其反序列化为实际的C int的最佳方法是简单地以值0开始,然后将每个八位字节的OR与值类似:
我最近一直在为稍微修改过的
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); } 这会让我有一个存储在值中的位模式,然后我可以通过强制它将其解释为带符号(二进制补码)整数: int64_t signed_value = static_cast<int64_t>(value); 但在我看来,这实际上是依赖于实现定义的行为.因此,为了将编码整数的实际值作为C int64_t,我需要实际计算位模式中每个第N位的2 ^ N的总和,同时考虑符号位.当我知道铸造应该在大多数时间工作时,这似乎有点傻. 这里有更好的解决方案既便携又高效? 解决方法
如果您的解决方案有效,我认为您可以使用一些元编程来测试您的平台是一个补码还是两个补码.
struct is_ones_complement { static const bool value = ( (1 & -1) == 0); } 然后,您可以编写一个无限转换函数: template<bool is_ones_complement> uint64_t convert_impl(const std::vector<uint8_t>& vec); template<> uint64_t convert_impl<true>(const std::vector<uint8_t>& vec) { // Your specialization for 1's-complement platforms } template<> uint64_t convert_impl<false>(const std::vector<uint8_t>& vec) { // Your specialization for 2's-complement platforms } inline uint64_t convert(const std::vector<uint8_t>& vec) { return convert_impl<is_ones_complement::value>(vec); } 未经测试,但它应该工作. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |