【问题标题】:Conversion of Binary into a Negative Integer将二进制转换为负整数
【发布时间】:2018-10-10 22:01:49
【问题描述】:

假设我有一组要转换为 int 的位,但这些位可能表示负 2 的补数,例如:

vector<bool> foo = { true, false, false, false, false, true, false, false }

显然,如果设置了foo.front(),则该数字为负数。将其转换为 int 的最佳方法是什么?


这个问题似乎不够清晰。作为参考,我在这里添加了我的蛮力解决方案:https://stackoverflow.com/a/50108264/2642059 我想完成同样的事情,但理想情况下是提供一些功能,而不是太多黑客。

【问题讨论】:

  • 你必须使用vector&lt;bool&gt;吗? std::bitset 应该为你处理这个问题。
  • 你可以得到unsigned int的值然后:int signed_val = *((int *)&amp;your_unsigned_int);
  • @NathanOliver 我不能使用bitset,因为我不知道在设计时我会有多少位,只是会少于 32 个。
  • 那么如果只提供 12 位,那么第 12 位将是符号位?
  • @NathanOliver 正确,如果 foo.front() 设置为负数。

标签: c++ binary integer twos-complement negative-number


【解决方案1】:
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();

【讨论】:

    【解决方案2】:

    在二进制补码表示法中,数字的负数是补码加 1。

    foo.first() == true时,将剩余元素全部转换为二进制数,然后取反加1。然后返回this的负数。

    因此,在您的示例中,其余元素对应于二进制数 0000000。将此补充到1111111,即127。添加1 得到128,然后返回-128。事实上,-128 的值在 8 位二进制补码中表示为 10000000

    您用于此过程的有符号数据类型需要至少比向量的大小大 1 位,以避免在“所有位设置”值加 1 时溢出。所以如果你的向量最多可以有32个元素(包括符号),你需要使用int64_t

    【讨论】:

    • 这些位已经在 2 的补码中。但看起来你的陈述是我应该设置所有前导位......
    • 已经是2的补码,但是向量的大小小于C++变量的位大小。
    【解决方案3】:

    数字的前导设置位,包括应为foo.front() 设置的位,可以通过执行以下操作生成:-(1 &lt;&lt; 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); });
    

    Live Example

    【讨论】:

      猜你喜欢
      • 2017-07-13
      • 2012-12-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-31
      • 2012-04-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多