Checking if an Integer is an Exact Binary Power
deadalnix via Digitalmars-d
digitalmars-d at puremagic.com
Mon Apr 25 15:42:38 PDT 2016
On Monday, 25 April 2016 at 12:56:27 UTC, Andrei Alexandrescu
wrote:
> On 4/25/16 6:42 AM, Solomon E wrote:
>> On Monday, 25 April 2016 at 05:35:12 UTC, Andrei Alexandrescu
>> wrote:
>>>
>>> With gdc https://godbolt.org/g/jcU4np isPow2B is the winner
>>> (shortest
>>> code, simplest instructions). -- Andrei
>>
>> I generalized function isPow2B to work for negative numbers in
>> case of a
>> signed type, while keeping the assembly the same or better.
>> (That also
>> incidentally made it correctly return false for zero.)
>>
>>> bool isPow2B(T)(T x)
>>> {
>>> return (x & -x) > (x - 1);
>>> }
>>
>> bool isPow2F(T)(T x)
>> {
>> return (x & -x) > (x >>> 1);
>> }
>>
>> assembly diff:
>> -- subl $1, %edi
>> ++ shrl %edi
>>
>
> That's smaller and faster, thanks. But how do you show it is
> still correct? -- Andrei
x & -x is the smallest power of 2 that divides x. Basically, if x
= xxxx1000 , x & -x = 00001000 . This is easy to proves
considering -x = ~x + 1 .
Now, x >> 1 will be of the form 0xxxx100 . If one of these digit
is one, then (x >> 1) >= (x & -x) . If they are all zeros, (x >>
1) < (x & -x) which is the case where you have a power of 2.
0 is a special case, can it can be checked that the function
return false for this specific input.
This looks like it is correct.
More information about the Digitalmars-d
mailing list