转换bitset <a> to signed int, with a&lt;32&gt;</a>

时间:2014-12-09 11:43:49

标签: c++ std bitset std-bitset

我正在阅读问题convert bitset to int in c++并且想,嘿,这不起作用,我已经尝试过了。但后来我开始尝试,很快就发现了:

#include <bitset>
#include <iostream>
int main()
{
   std::bitset<31> b31(-1);
   std::bitset<32> b32(-1);
   std::cout<<static_cast<int>(b31.to_ulong())<<std::endl;
   std::cout<<static_cast<int>(b32.to_ulong())<<std::endl;
   return 0;
}

给出输出

2147483647
-1

那么,如何将小于32的位集转换为有符号整数?

澄清:我想在构造保留的位集时使用10-base值转换为signed int。 “存储在bitsets中签名的内容”

我尝试使用gcc 4.6.2,在win 7上使用mingw32,并使用c-style强制转换获得相同的结果(int)

3 个答案:

答案 0 :(得分:2)

这些方面的内容如何:

#include <bitset>
#include <iostream>

template<std::size_t B>
long bitset_to_long(const std::bitset<B>& b) {
  struct {long x:B;} s;
  return s.x = b.to_ulong();
}

int main()
{
   std::bitset<31> b31(-1);
   std::bitset<32> b32(-1);
   std::cout << bitset_to_long(b31) << std::endl;
   std::cout << bitset_to_long(b32) << std::endl;
   return 0;
}

(灵感来自Sign extending from a constant bit-width。)

答案 1 :(得分:1)

创建一个掩码,其中剩余的高位中有一个,当位集中的最高有效位设置为1时,将其与来自强制转换的无符号值进行OR运算,如下所示:

const int sz = 15;
std::bitset<sz> b(-1);
int num = static_cast<int>(b.to_ulong());
if (b[sz-1]) {
    int mask = (1<<sz)-1;
    num |= ~mask;
}
std::cout << num << std::endl;

表达式(1<<sz)生成一个仅设置sz位的数字。 (1<<sz)-1生成一个掩码,其最后sz-1位设置为1 s。 ~将其反转,产生对位集值的二进制补码。

Demo.

答案 2 :(得分:0)

您需要签名扩展

#define BITLEN 31
#define SHIFT_AMOUNT (sizeof(int)*CHAR_BIT - BITLEN)

std::bitset<BITLEN> b31(-1);
int v = (static_cast<int>(b31.to_ulong()) << SHIFT_AMOUNT) >> SHIFT_AMOUNT;
std::cout << v << std::endl;