Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
右移位将C中无符号整数的开头加1_C_Bit Shift - Fatal编程技术网

右移位将C中无符号整数的开头加1

右移位将C中无符号整数的开头加1,c,bit-shift,C,Bit Shift,我试图在C语言中移动一个16位地址来获得一个缓存模拟器的设置ID,但当我尝试向右移动时,我的数字上会多出一个1 我的电话号码是0010100011001。然后左移3位,得到0100011001000。到现在为止,一直都还不错。但是,我随后尝试右移6位,结果是00000 10100010011,而不是0000000 100010011。我所有的整数都是无符号的,当我尝试移位时,它只加一个1 我的尝试和转换代码如下。在我的示例中,tag_大小为3,b为6 unsigned int temp

我试图在C语言中移动一个16位地址来获得一个缓存模拟器的设置ID,但当我尝试向右移动时,我的数字上会多出一个1

我的电话号码是0010100011001。然后左移3位,得到0100011001000。到现在为止,一直都还不错。但是,我随后尝试右移6位,结果是00000 10100010011,而不是0000000 100010011。我所有的整数都是无符号的,当我尝试移位时,它只加一个1

我的尝试和转换代码如下。在我的示例中,tag_大小为3,b为6

    unsigned int temp = addr << tag_size;
    unsigned int temp1 = temp >> b;
    unsigned int setid = temp1 >> tag_size;
unsigned int temp=addr>b;
unsigned int setid=temp1>>标记大小;

16位
int
s现在已经不常见了。您可以尝试将变量定义为
short
,通常为16位。这完全取决于你使用的机器。如果要查找16位整数,也可以使用
uint16

看起来问题可能是因为您使用的
无符号int
实际上不是Christian Gibbons在评论中提到的16位。当您将
0010100011001
左移3位时,您会得到
1010001001001000
,最左边的1不会像您在16位整数中预期的那样被删除,然后当您再次右移时,您会得到不期望的添加1

您可以将代码更改为此,并且它应该按照您最初的预期工作:

uint16_t temp = addr << tag_size;
uint16_t temp1 = temp >> b;
uint16_t setid = temp1 >> tag_size;
uint16\u t temp=addr>b;
uint16\u t setid=temp1>>标记大小;

您应该使用掩码并选择您感兴趣的位;例如:

unsigned int temp = (addr << tag_size) & 0xffffu; // keep 16 low bits
unsigned int temp1 = temp >> b;
unsigned int setid = temp1 >> tag_size;

unsigned int temp=(addr>(b+标记大小);

这使得代码独立于
无符号int
大小,C保证至少为16位。

请显示。通过输入和输出,您的系统实际上是否有16位
int
s?看起来像“添加”1是移位超过第16位的同一个。这实际上是对可能发生的情况的一个很好的总结。关于使用精确宽度类型
uint15\t
的好建议。虽然不是必需的,但如果您能胜任,一个简短的片段显示如何实现您的建议通常会增加您答案的价值。感谢您的改进我向OP的原始代码片段添加了一个建议更改。
unsigned int temp = addr & (0xffffu >> tag_size); // keep 16 low bits
unsigned int setid = temp >> b;
unsigned int temp = (addr << tag_size) & 0xffffu; // keep 16 low bits
unsigned int setid = temp >> (b + tag_size);