std::numeric_limits::min() - на самом деле не совсем min (и это не про отрицательные значения)

Удивило что код:

log_file << "\n" << std::numeric_limits<double>::max();
log_file << "\n" << std::numeric_limits<double>::min();
double test = 1e-10;
for (size_t i = 0; i < 31; i++)
    test *= 1e-10;
log_file << "\n" << test;

Выдаёт результат:

1.79769e+308
2.22507e-308
9.99989e-321

Т.е. double test может хранить значение заметно меньше чем std::numeric_limits<double>::min(). И только если цикл до i < 32; то test выводится как ноль.

Аналогичный тест с умножением на 1e10 показывает что с ::max() всё в порядке и при превышении e+308 testстановится inf.

Есть версии почему так?


Ответы (1 шт):

Автор решения: HolyBlackCat
std::cout << std::numeric_limits<double>::min() << '\n';        // 2.22507e-308
std::cout << std::numeric_limits<double>::denorm_min() << '\n'; // 4.94066e-324

min() выдает самое маленькое по модулю не-денормализованное число. Денормализованные могут быть меньше. Минимальное число с учетом денормализованных - denorm_min().

→ Ссылка