# 回顾

``````int isPowerOf2a(long x)
{
if (x <= 0) return 0;
while (x % 2 == 0) x /= 2;
return x == 1;
}
``````

``````while ((x & 1) == 0) x >>= 1;
``````

\$ clang -O isPowerOf2.c && ./a.out

``````isPowerOf2a:  49.7 seconds, 34
isPowerOf2b:  41.5 seconds, 34
isPowerOf2c:  29.7 seconds, 34
isPowerOf2d:  32.7 seconds, 34
``````

# 反汇编

1. `z >>>= 63;` // z = (x < 0) ? 1 : 0;
2. `z += x;`     // z = (x < 0) ? (x+1) : x;
3. `z >>= 1;`   // z /= 2;
4. `x = z;`

``````if (x <= 0) return 0;
``````

# 使用无符号整数

\$ clang -O isPowerOf2u.c && ./a.out

``````isPowerOf2a:  38.1 seconds, 34
isPowerOf2b:  38.9 seconds, 34
isPowerOf2c:  25.0 seconds, 34
isPowerOf2d:  32.9 seconds, 34
``````

 ``` 0: 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: ``` ```0000000000400520 : 400520: xor %eax,%eax 400522: test %rdi,%rdi 400525: je 400544 400530: mov %rdi,%rax 400533: shr %rdi 400536: test \$0x1,%al 400538: je 400530 40053a: cmp \$0x1,%rax 40053e: sete %al 400541: movzbl %al,%eax 400544: retq ``` ```0000000000400550 : 400550: xor %eax,%eax 400552: test %rdi,%rdi 400555: je 400574 400560: mov %rdi,%rax 400563: shr %rdi 400566: test \$0x1,%al 400568: je 400560 40056a: cmp \$0x1,%rax 40056e: sete %al 400571: movzbl %al,%eax 400574: retq ```

• 第 3 行：`jle`指令改为`je`指令，即`x <= 0`改为`x == 0`
• 第 5 行：`sar`指令改为`shr`指令，即`算术右移`改为`逻辑右移`