是否可以转换0
,因为您可以在C中转换操作时转换1
?
像这样的东西
for (i=0; i<32; i++) {
if (data & 0x01) {
data |= (1<<i);
}
else {
data &=~ (0<<i);
}
}
我正在检查某些位是否已设置,并且根据我在新变量中存储0
s或1
s,将每一位向左移位。
答案 0 :(得分:3)
您不会移动0
或1
,您可以移位位值,无论是0
还是1
。换句话说,无论存储在中的值,都可以移动位位置。
从C11
标准,章节§6.5.7。 ,按位移位运算符
E1 << E2
的结果是E1
左移E2
位位置;腾出的位用零填充。
就像那样,在1
s的情况下,移动可见。
也就是说,<
不 是一个位移运算符(如代码中所示),<<
是。
答案 1 :(得分:2)
<<
(不是<
!)不会移位一位。它改变了整数。当你说1<<5
时,它会向左移动0000000000000001
五个位置(给定一个16位值),这会给出0000000000100000
。 0<<5
正在移动0000000000000000
五个位置,这会产生0000000000000000
(即相同的值)。其他位不是不确定的:你不能移动一个位(我假设你想要??????????1?????
和??????????0?????
之类的东西,但是数字不会像那样工作。)
这看起来像是典型的XY问题。您可能希望使用data
来打开或关闭其他内容?询问那个。 (编辑:正如Joachim Pileborg在评论中所说的那样。)
答案 2 :(得分:1)
好消息是 - 你过度思考它。
取整数,说:01011011
。
将其左移1:10110110
。
整个事情&#39;一起转移;零被移入LSB。在右移的情况下,对于无符号或对已签名数字的实现定义,它再次为零:
E1&gt;的结果&gt; E2是E1右移E2位位置。如果E1具有无符号类型或者E1具有带符号类型和非负值,则结果的值是E1 / 2E2的商的整数部分。如果E1具有有符号类型和负值,则结果值是实现定义的。
(S6.5.7)
这意味着右移有符号数可能会导致算术移位或逻辑移位。
如果你想将1
转移到低端,而不是0
s,只需用一个位掩码来表示你转移的位数。
答案 3 :(得分:0)
使用CPU寄存器执行移位操作。寄存器由许多位组成(8,16和32是常见的,你似乎有32个CPU),它们的组合可以解释为十进制值。
在您的示例中,您使用值1.C语言允许以多种方式表示值1,所有这些都会导致CPU寄存器的相同内容:
decimal hexadecimal binary
1 0x00000001 0b00000000000000000000000000000001
3713883835 0xDD5D5EBB 0b11011101010111010101111010111011
(在所有情况下,可以省略前导0
。)
在二进制表示中,指定了所有CPU寄存器位值。如您所见,这包括0和1。因此,当您将值1置于寄存器中并使用<<
运算符执行左移时,整个寄存器的内容将向左移位一位,并将0置于最低有效位。
在您的代码中,分配给数据的值将遵循以下模式:
i = 0, data = 0x00000000000000000000000000000001
i = 1, data = 0x00000000000000000000000000000010
i = 2, data = 0x00000000000000000000000000000100
etc.
i = 30, data = 0x01000000000000000000000000000000
i = 31, data = 0x10000000000000000000000000000000
如果您要使用不同于1的值来移动,您当然会以不同的模式结束,但它会遵循相同的规则。即无论是否保持1或0,所有位都会移位。
for(i=0;i<32;i++)
{
data = (165 << i) // 165 = 0xA5 = 0b10100101
}
Produces:
i = 0, data = 0x00000000000000000000000010100101
i = 1, data = 0x00000000000000000000000101001010
i = 2, data = 0x00000000000000000000001010010100
etc.
i = 28, data = 0x10100000000000000000000000000000
i = 29, data = 0x01000000000000000000000000000000
i = 30, data = 0x10000000000000000000000000000000
i = 31, data = 0x00000000000000000000000000000000
注意当最高有效位移出寄存器时,模式会如何消失。
使用>>
运算符执行右移的规则相同,只是位从最重要位移到最小位。
(有些CPU也有旋转和其他精彩的位操作指令。)