为什么 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)
此表达式在编译时计算,因此结果与您自己计算常量的结果相同。
请注意,0x8000
和 0x80000000
常量都是系统相关的。此外,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) ;
}
我正在尝试将向量中的值放入 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)
此表达式在编译时计算,因此结果与您自己计算常量的结果相同。
请注意,0x8000
和 0x80000000
常量都是系统相关的。此外,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) ;
}