将二进制转换为负整数
Conversion of Binary into a Negative Integer
假设我有一组要转换为 int
的位,但这些位可能表示负 2 的补码,例如:
vector<bool> foo = { true, false, false, false, false, true, false, false }
显然,如果设置了 foo.front()
,则该数字为负数。将其转换为 int
的最佳方法是什么?
这个问题好像不太清楚。作为参考,我在此处添加了我的蛮力解决方案: 我想完成同样的事情,但理想情况下具有一些提供的功能,而不是那么多黑客。
在二进制补码中,一个数的负数是补码加 1。
当foo.first() == true
时,将剩余的元素全部转为二进制数,然后取反加1,然后return这个的负数
所以在你的例子中,剩余的元素对应于二进制数0000000
。将此补充到 1111111
,即 127
。添加 1
得到 128
,然后得到 return -128
。实际上,值 -128
在 8 位二进制补码中表示为 10000000
。
您在此过程中使用的有符号数据类型需要至少比向量大小大 1 位,以避免在 "all bits set" 值加 1 时溢出。所以如果你的vector最多可以有32个元素(包括符号),你需要使用int64_t
.
数字的前导设置位,包括应该为 foo.front()
设置的位,可以通过执行以下操作生成:-(1 << size(foo) - 1)
。在此之后,您只需要移动剩余的位即可。
例如,无论是否设置了 foo.front()
,都会生成正确的数字:
int i = size(foo) - 1;
const auto bar = accumulate(next(cbegin(foo)), cend(foo), foo.front() ? -(1 << i) : 0, [&](const auto val, const auto it) { return val + (it << --i); });
std::vector<bool> foo;
//...
long long val=0;
for(auto& bit:foo){
val<<=1;
val+=bit;
};
if(foo.front())//sign extension
val+=~0ll<<foo.size();
假设我有一组要转换为 int
的位,但这些位可能表示负 2 的补码,例如:
vector<bool> foo = { true, false, false, false, false, true, false, false }
显然,如果设置了 foo.front()
,则该数字为负数。将其转换为 int
的最佳方法是什么?
这个问题好像不太清楚。作为参考,我在此处添加了我的蛮力解决方案:
在二进制补码中,一个数的负数是补码加 1。
当foo.first() == true
时,将剩余的元素全部转为二进制数,然后取反加1,然后return这个的负数
所以在你的例子中,剩余的元素对应于二进制数0000000
。将此补充到 1111111
,即 127
。添加 1
得到 128
,然后得到 return -128
。实际上,值 -128
在 8 位二进制补码中表示为 10000000
。
您在此过程中使用的有符号数据类型需要至少比向量大小大 1 位,以避免在 "all bits set" 值加 1 时溢出。所以如果你的vector最多可以有32个元素(包括符号),你需要使用int64_t
.
数字的前导设置位,包括应该为 foo.front()
设置的位,可以通过执行以下操作生成:-(1 << size(foo) - 1)
。在此之后,您只需要移动剩余的位即可。
例如,无论是否设置了 foo.front()
,都会生成正确的数字:
int i = size(foo) - 1;
const auto bar = accumulate(next(cbegin(foo)), cend(foo), foo.front() ? -(1 << i) : 0, [&](const auto val, const auto it) { return val + (it << --i); });
std::vector<bool> foo;
//...
long long val=0;
for(auto& bit:foo){
val<<=1;
val+=bit;
};
if(foo.front())//sign extension
val+=~0ll<<foo.size();