为什么无符号整数左移从第16位发生?

时间:2015-11-15 16:03:45

标签: c++11 binary bit-manipulation

我试图将vector中的值放入int中。

  

给定向量:'1','0','1','1','1','0','1','1','1','0','1', '1','1','0','1','1':

预期输出(变量输出的二进制表示):

  

00000000000000001011101110111011。

但是,我得到以下输出:

  

10111011101110110000000000000000

注意:插入从右端开始是16位而不是从最左边的位开始

#include<vector>
#include<iostream>

int main() {

   std::vector<unsigned char> test = {'1','0','1','1','1','0','1','1','1','0','1','1','1','0','1','1'};

   std::vector<unsigned int> out(1);

   int j = 0;

   for (int i =0; i < test.size(); i++) {
      out[j] = out[j] << 1;
      if (test[i] == '1') {out[j] |=0x1;}

   }

   j++;

   for (int p = 0; p < j; p++) {

      for (int k = 0; k<32; k++ ) {
         std::cout << !!((out[p]<<k)&0x8000);
      }
      std::cout << std::endl;
   }

   std::cout << "Size Of:" << sizeof(int);

   return 0;
}

3 个答案:

答案 0 :(得分:1)

发生这种情况的原因是你为掩码使用了一个错误的常量:0x8000有16位设置,而你可能意味着使用0x80000000和32位设置。为了避免这样的错误,最好构建带有移位的蒙版,例如

(1 << 31)

此表达式在编译时计算,因此结果与您自己计算常量的结果相同。

请注意,0x80000x80000000常量都与系统有关。此外,0x80000000假定为32位int,但无法保证。

更好的方法是将数字右移而不是左移,并使用1进行屏蔽。

答案 1 :(得分:0)

创建out[j]的代码块工作正常。

由于使用0x8000,您的问题出在输出块中。每当k >= 16时,低16位将为零,保证0x8000为零。

答案 2 :(得分:0)

您的代码对我来说似乎过于复杂。这是我的C程序版本,它将1和0的字符串转换为int,从int转换为字符串。

#include <stdlib.h>
#include <stdio.h>

int main(int argc, char **argv);

int main (int argc, char **argv)  {
   char str [] = "1010101010101010";

   int x;
   int out;
   for (x=0;x<16;x++)  {
      if (str[x] == '1') {
         out |= (1 << x);
      }
   }
   printf("%d", out) ;
}      

   #include <stdlib.h>
    #include <stdio.h>

    int main(int argc, char **argv);

    int main (int argc, char **argv)  {
       char str [] = "1010101010101010";

       int in = 21845;
       char out[17] = {0};
       for (x=0;x<16;x++)  {
          if (in & (1<<x)) {
             out[x] = '1';
          }
          else {
             out[x] = '0';
          }
       }
       printf("%s", out) ;
    }