Checking if an Integer is an Exact Binary Power
Xinok via Digitalmars-d
digitalmars-d at puremagic.com
Sun Apr 24 18:17:48 PDT 2016
On Sunday, 24 April 2016 at 23:17:53 UTC, David Nadlinger wrote:
> On Sunday, 24 April 2016 at 23:00:56 UTC, Temtaime wrote:
>> Please no cmp.
>> Just
>> bool isPowerOf2(uint x) { return x && !(x & (x - 1)); }
>
> You do realise that this will (typically) emit a branch?
>
> — David
I compiled using dmd -O and looked at the disassembly using
objdump -D and there are indeed a couple branches in the
disassembly:
0000000000000000 <_D4test8powerOf2FkZk>:
0: 50 push %rax
1: 48 89 f9 mov %rdi,%rcx
4: 85 c9 test %ecx,%ecx
6: 74 0a je 12
<_D4test8powerOf2FkZk+0x12>
8: 8d 81 ff ff ff ff lea -0x1(%rcx),%eax
e: 85 c1 test %eax,%ecx
10: 74 04 je 16
<_D4test8powerOf2FkZk+0x16>
12: 31 c0 xor %eax,%eax
14: eb 05 jmp 1b
<_D4test8powerOf2FkZk+0x1b>
16: b8 01 00 00 00 mov $0x1,%eax
1b: 59 pop %rcx
1c: c3 retq
1d: 0f 1f 00 nopl (%rax)
I modified David's solution a bit to (hopefully) eliminate the
branch:
bool powerOf2(uint x){ return !x ^ !(x & (x - 1)); }
0000000000000000 <_D4test8powerOf2FkZb>:
0: 50 push %rax
1: 53 push %rbx
2: 48 89 fa mov %rdi,%rdx
5: 85 d2 test %edx,%edx
7: 0f 94 c0 sete %al
a: 8d 8a ff ff ff ff lea -0x1(%rdx),%ecx
10: 85 ca test %ecx,%edx
12: 0f 94 c3 sete %bl
15: 32 c3 xor %bl,%al
17: 5b pop %rbx
18: 59 pop %rcx
19: c3 retq
1a: 66 0f 1f 44 00 00 nopw 0x0(%rax,%rax,1)
The branches are gone but I'm really not sure if this is better
or worse.
More information about the Digitalmars-d
mailing list