为什么 unsigned int 从第 16 位开始左移?

Why does the left shift on a unsigned int happens from the 16th bit?

我正在尝试将向量中的值放入 int 中。

Given vector :'1','0','1','1','1','0','1','1','1','0','1','1','1','0','1','1' :

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

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;
}

创建 out[j] 的代码块工作得很好。

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

发生这种情况的原因是您使用了错误的掩码常量:0x8000 设置了 16 位,而您可能打算将 0x80000000 与 32 位一起使用位设置。为避免这样的错误,最好构造带移位的掩码,例如

(1 << 31)

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

请注意,0x80000x80000000 常量都是系统相关的。此外,0x80000000 假定 32 位 int,这是无法保证的。

更好的方法是将数字 右移 而不是左移,并使用 1.

进行遮蔽

我觉得你的代码太复杂了。这是我的 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) ;
    }