I have to check a number if it satisfies the following criteria:
I wrote a code that checks for these conditions for a real-world problem (checking data-file integrity).
It works without problems and it's anything but time-critical, but I'm an old bit-twiddeling freak and love such puzzles, so I've tried to came up with a more clever way to check for single-one-bit streams.
Cases where the string is surrounded by zeros is easy, but that one can't deal with the special cases.
Any ideas, binary hacks and partial solutions are welcome!
To make my requirements more clear some examples: The following numbers satisfy my criteria:
0x80000000
0x00000001
0xff000000
0x000000ff
0xffffffff
0x000ff000
The following numbers don't (as they have more than one successive string of ones):
0xf00000f <- one-bit streams should not wrap-around at 2^n
0x0001700 <- a trivial example.
0x0000000 <- no one bit at all.
This should do what you want.
if(i == 0)
return false;
while(i % 2 == 0) {
i = i / 2;
}
return (i & (i + 1)) == 0;
bool isOK(uint val) {
while (val != 0 && (val & 1u) == 0) val >>= 1;
if (val == 0) return false;
while (val != 0 && (val & 1u) == 1) val >>= 1;
return val == 0;
}
; x86 assembly
mov eax, THE_NUMBER ; store the number in eax
bsf ecx, eax
jz .notok
mov edi, 1
shl edi, cl
mov esi, eax
add esi, edi
test esi, eax
jnz .notok
mov eax, 1
jmp .end
.notok:
mov eax, 0
.end: ; eax = 1 if satisfies the criteria, otherwise it's 0
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With