Float содержит 23 бита мантиссы и неявную единицу. Порядок float запредельный и даже qword не упрётся в него.
Это значит: всё, что дальше 23 бит от верхней единицы, должно быть нулём.
bool isPreciseFloat(unsigned long long n)
{
// Простейшая проверка: стираем нижние 24 бита
// Если в них вписываемся — ДА.
unsigned long long n1 = n & ~((1ULL << 24) - 1);
if (n1 == 0)
return true;
// Получаем верхнюю единицу
// (можно также двоичным поиском, но я этого с листа не напишу)
while (true) {
unsigned long long n2 = n1 & (n1 - 1);
if (n2 == 0)
break;
n1 = n2;
}
// Получаем маску всего, что ниже 23 бит от верхнего бита.
n1 >>= 23;
--n1;
// Проверяем по маске
return (n & n1) == 0;
}
Писал «с листа», могут быть ошибки.