Вариант это один:
double log10_value= log10(value);
double integer_value;
double fractional_value= modf(log10_value, &integer_value);
return fractional_value==0.0;
Обратите внимание, что сравнение с 0.0
является точным, а не внутри конкретного эпсилона, поскольку вы хотите убедиться, что log10_value
является целым числом.
РЕДАКТИРОВАТЬ: Так как это вызвало небольшую полемику из-за возможной неточности log10
и общего понимания, что вы не должны сравнивать двойные числа без эпсилона, вот более точный способ определить, является ли двойная степень степенью 10 используя только свойства степеней 10 и двойников IEEE 754.
Во-первых, уточнение: двойное число может представлять до 1E22, поскольку 1e22 имеет только 52 значащих бита. К счастью, 5 ^ 22 также имеет только 52 значащих бита, поэтому мы можем определить, является ли удвоение (2*5)^n
для 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;
}
}
Начиная с 2^10==1024
, это добавляет дополнительный бит значимости, который мы должны удалить из возможной степени 5.