我想在没有循环的情况下进行n次切换 切换3次后的1(位)将为0,依此类推。 为了切换1次,我使用bit ^ = 1。 我实际上搜索了一些操作公式来这样做。
答案 0 :(得分:6)
如果我理解正确,您需要稍微切换N
次。
现在,切换bin N次等于切换N%2次,所以:
b ^= (N%2);
模2与N&1
相同,所以你也可以写:
b ^= (N&1);
答案 1 :(得分:1)
广义解决方案:
String
gcc 5.3生成此代码:
int toggle_bit_in_word(int word, int bit, int ntimes)
{
auto archetype = ntimes & 1;
auto toggler = archetype << bit;
return word ^= toggler;
}
为了好玩,让我们把它写成一种方式,享受欢乐:
toggle_bit_in_word(int, int, int):
and edx, 1
shlx edx, edx, esi
mov eax, edx
xor eax, edi
ret
输出(5.3):
int toggle_bit_in_word_naiive(int word, int bit, int ntimes)
{
auto toggler = 1 << bit;
while (ntimes--)
word ^= toggler;
return word;
}
8 - /
当然,当优化者拥有所需的所有信息时,即使是有效的代码也会变得高效:
toggle_bit_in_word_naiive(int, int, int):
mov ecx, 1
mov eax, edi
shlx esi, ecx, esi
lea edi, [rdx-1]
test edx, edx
je .L48
lea ecx, [rdx-8]
shr ecx, 3
add ecx, 1
lea r9d, [0+rcx*8]
cmp edi, 12
jbe .L4
vmovd xmm1, esi
xor r8d, r8d
vpxor xmm0, xmm0, xmm0
vpbroadcastd ymm1, xmm1
.L5:
add r8d, 1
vpxor ymm0, ymm0, ymm1
cmp ecx, r8d
ja .L5
vpxor xmm1, xmm1, xmm1
vperm2i128 ymm2, ymm0, ymm1, 33
vpxor ymm0, ymm0, ymm2
sub edi, r9d
vperm2i128 ymm2, ymm0, ymm1, 33
vpalignr ymm2, ymm2, ymm0, 8
vpxor ymm0, ymm0, ymm2
vperm2i128 ymm1, ymm0, ymm1, 33
vpalignr ymm1, ymm1, ymm0, 4
vpxor ymm0, ymm0, ymm1
vmovd ecx, xmm0
xor eax, ecx
cmp edx, r9d
je .L47
vzeroupper
.L4:
xor eax, esi
test edi, edi
je .L48
xor eax, esi
cmp edi, 1
je .L48
xor eax, esi
cmp edi, 2
je .L48
xor eax, esi
cmp edi, 3
je .L48
xor eax, esi
cmp edi, 4
je .L48
xor eax, esi
cmp edi, 5
je .L48
xor eax, esi
cmp edi, 6
je .L48
xor eax, esi
cmp edi, 7
je .L48
xor eax, esi
cmp edi, 8
je .L48
xor eax, esi
cmp edi, 9
je .L48
xor eax, esi
cmp edi, 10
je .L48
xor eax, esi
xor esi, eax
cmp edi, 11
cmovne eax, esi
ret
.L47:
vzeroupper
.L48:
ret
结果:
int main(int argc, char**argv)
{
return toggle_bit_in_word_naiive(argc, 3, 3);
}
答案 2 :(得分:0)
如果您只是独立操作位,这是不可能的。
那是因为某个特定位不知道其前两个状态。
如果您想要一个周期为4的循环,则至少需要2位。