C++: how can I test if a number is power of ten?

前端 未结 9 1296
清歌不尽
清歌不尽 2021-02-18 19:12

I want to test if a number double x is an integer power of 10. I could perhaps use cmath\'s log10 and then test if x == (int) x?

<

9条回答
  •  花落未央
    2021-02-18 19:26

    A variant of this one:

    double log10_value= log10(value);
    double integer_value;
    double fractional_value= modf(log10_value, &integer_value);
    
    return fractional_value==0.0;
    

    Note that the comparison to 0.0 is exact rather than within a particular epsilon since you want to ensure that log10_value is an integer.

    EDIT: Since this sparked a bit of controversy due to log10 possibly being imprecise and the generic understanding that you shouldn't compare doubles without an epsilon, here's a more precise way of determining if a double is a power of 10 using only properties of powers of 10 and IEEE 754 doubles.

    First, a clarification: a double can represent up to 1E22, as 1e22 has only 52 significant bits. Luckily, 5^22 also only has 52 significant bits, so we can determine if a double is (2*5)^n for n= [0, 22]:

    bool is_pow10(double value)
    {
        int exponent;
        double mantissa= frexp(value, &exponent);
    
        int exponent_adjustment= exponent/10;
    
        int possible_10_exponent= (exponent - exponent_adjustment)/3;
    
        if (possible_10_exponent>=0 && 
            possible_10_exponent<=22)
        {
            mantissa*= pow(2.0, exponent - possible_10_exponent);
    
            return mantissa==pow(5.0, possible_10_exponent);
        }
        else
        {
            return false;
        }
    }
    

    Since 2^10==1024, that adds an extra bit of significance that we have to remove from the possible power of 5.

提交回复
热议问题