据我所知,当你在C语言中使用按位左移运算符时,可以保证空位会被0填充,然而,我读到过右移是依赖于实现的,这意味着在一些机器中,空位会被0填充,而在另一些机器中,空位会被1填充。
我在一个程序中使用了右移位,我的机器确实用1填充了空位,问题是我需要用0来代替。
有没有办法强迫0在正确的班次使用?
一种解决方案是,在应用右移之后,创建一个类似于011111111的掩码,然后应用逐位AND,这将把插入的最左边的1更改为0。
但这很麻烦,也很浪费时间。如果有一种方法可以告诉我的机器用1来填充正确的班次,那就容易多了。
谢谢
3条答案
按热度按时间de90aj5v1#
将数字转换为
unsigned
,然后按shift。这将强制填充0。qncylg1j2#
不,你不能。
无符号类型上的移位是明确定义的(只要右操作数为非负且小于左操作数的宽度),并且它们总是填充零。
班次(或任何按位运算)通常不是一个好主意。如果左操作数为负,则
<<
具有未定义的行为,并且>>
生成实现定义的结果(这意味着编译器必须记录它所做的事情,但您无法控制它)。对于带符号类型的非负值,结果是您所期望的--只要它不溢出(如果溢出,行为是未定义的)。C99 standard的说明如下(第6.5.7节):
对每个操作数执行整数提升。结果的类型是提升的左操作数的类型。如果右操作数的值为负值,或者大于或等于提升的左操作数的宽度,则行为未定义。
11年多以后再回到这个问题上,一个实现当然可以提供一个选项来控制实现定义的移位行为,我不知道有哪个实现这样做。
我引用的是C99标准,我不相信以后的版本会有相关的变化。
jdgnovmf3#
有两种不同的右移操作:算术和逻辑。
在C语言中,逻辑移位用于无符号数。它总是用零填充高位。这就是你需要的。
算术移位用于有符号数,因为它保留了被移位数的符号。如果数为正数,则最高有效位将为0,并且将用0填充。如果数为负数,则最高有效位将为1,因此将用1填充。
注意,在Java中,它们实际上使用不同的操作符:
>>
表示算术,>>>
表示逻辑。这是必需的,因为Java没有无符号类型。