Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Code for check if double is a power of 2 without bit manipulation in C++

For checking if a double is a power of 2 I found this code:

unsigned long long int &p= *(unsigned long long int *) &x;
unsigned int exp= (p >> 52) & 0x7FF;
if ( exp == 0 || exp == 0x7FF ) return false;
return (p & 0xFFFFFFFFFFFFFULL) == 0; 

However it fails basic tests for some architectures. I guess that's because different lenght of integers. So I tried to figure out a simple alternative that does not do bit manipulation:

bool isPot(double a ){
    return a==0.? false : (1./a)*a==1.;
}

The assumption is that any division by a number that is not a power of 2 generates infinite digits in the mantissa, so since values are truncated, it will not yield 1 when multiplied by its inverse.

However, it apparently works, but I cannot proove that because bruteforcing a test for all values would require ~140 years.

Suggestions?

MyTests:

assert(isPot(2.0)); //first solution fails here
assert(isPot(0.5));
assert(!isPot(5.0));
assert(!isPot(0.2));

By Power of 2, I mean a value that is exactly a power of 2 once stored in RAM. so a number with all mantissa bits that are 0. This is implicitly a solution that has a inherent error because assume the following value:

2.000000000000000000000000000000000000000000000000000000000000003

it would be converted to

2.0

and so returns true because has all mantissa bits to 0, but originally it was not a power of 2.

like image 914
CoffeDeveloper Avatar asked Dec 19 '14 12:12

CoffeDeveloper


People also ask

How to check if a number is power of 2 bit manipulation?

If (x & (x-1)) is zero then the number is power of 2. For example, let x be 8 ( 1000 in binary); then x-1 = 7 ( 0111 ). This outputs the bit is power of 2 . This outputs the bit is not power of 2 .

How to test if something is a power of 2?

Keep dividing the number by two, i.e, do n = n/2 iteratively until n becomes 1. In any iteration, if n%2 becomes non-zero and n is not 1 then n is not a power of 2. If n becomes 1 then it is a power of 2.

What is the operator for double?

Definition of "==" operator for Double.


1 Answers

You can use frexp as a portable way to split the double into exponent and mantissa, and then check that the mantissa is exactly 0.5.

example:

#include <math.h>

bool isPow2(double x)
{
    int exponent = 0;
    auto mantissa1 = frexp(x, &exponent);
    return mantissa1 == 0.5;
}

BOOST_AUTO_TEST_CASE(powers_of_2)
{
    std::vector<double> yes { 1, 2, 4, 8, 16, 0.5, 0.25, 65536 };
    std::vector<double> no { 0, 3, 7, 15, 0.51, 0.24, 65535 };


    for (size_t i = 0 ; i < yes.size() ; ++i) {
        BOOST_CHECK_EQUAL(isPow2(yes[i]), true);
    }
    for (size_t i = 0 ; i < no.size() ; ++i) {
        BOOST_CHECK_EQUAL(isPow2(no[i]), false);
    }
}
like image 92
Alan Stokes Avatar answered Oct 06 '22 02:10

Alan Stokes