在C中,通过常数进行的位移位与通过具有相同值的变量进行的位移位之间是否存在差异?
我试图将值在C中,通过常数进行的位移位与通过具有相同值的变量进行的位移位之间是否存在差异?,c,bit-shift,C,Bit Shift,我试图将值0xFFFFFFFF进行32位的位移位,它正确地到达 如果我写 x = x << 32; 当y=32时 我真的一点也不明白 我需要能够使用一个变量,用于移位32-n的函数 编辑 如果将一个变量移位其包含的位数或更多,则这是未定义的行为。假设x为32位,则不存在“正确”结果 我使用的编译器识别此编程错误: x.c:3:3: error: left shift count >= width of type [-Werror] 如果y的类型为int(因为文字32也是in
0xFFFFFFFF
进行32位的位移位,它正确地到达
如果我写
x = x << 32;
当y=32时
我真的一点也不明白
我需要能够使用一个变量,用于移位32-n的函数
编辑
如果将一个变量移位其包含的位数或更多,则这是未定义的行为。假设x
为32位,则不存在“正确”结果
我使用的编译器识别此编程错误:
x.c:3:3: error: left shift count >= width of type [-Werror]
如果y
的类型为int
(因为文字32
也是int
)并且您的程序定义了行为,则行为没有区别
如果x
是32
位宽的类型,那么您的程序将调用未定义的行为,因此一切都可能发生 它是按一个变量或更大的位长度移位。从C99标准草案部分6.5.7
按位移位运算符:
[…]如果右操作数的值为负或大于或等于提升后的左操作数的宽度,则行为未定义
正如Pascal所说,您需要制作一个特殊的案例或使用更广泛的类型
gcc
在某些情况下,可能会为此生成警告:
警告:左移位计数>=类型的宽度[默认启用]
您可能希望执行以下操作:
unsigned int x;
unsigned long bx = ((unsigned long)x)&0xFFFFFFFFUL;
int n = 0; // put whatever you have
int y = 32-n;
bx = bx << y;
x = bx&0xFFFFFFFFUL;
无符号整数x;
无符号长bx=((无符号长)x)&0xfffffful;
int n=0;//把你所有的都放进去
int y=32-n;
bx=bx如果x
是32位,这是未定义的行为。回答您的编辑:您有两种解决方案:要么制作一个特例,要么使用比int
更宽的类型(简单到(int)(0xfffffffffullIf(y>=32)x=MIN_INT;
@PascalCuoq或使用查找表并避免分支。您使用的是哪种编译器?通常会收到警告。当然,根据您的实际处理器字长,您可能必须使用无符号long-long。在某些系统上,无符号long
和无符号INT
的长度可能相同。
unsigned int x;
unsigned long bx = ((unsigned long)x)&0xFFFFFFFFUL;
int n = 0; // put whatever you have
int y = 32-n;
bx = bx << y;
x = bx&0xFFFFFFFFUL;