Может ли std ::iform_real_distribution & lt; double & gt; (0,1) вернуть значение больше 0,999999999999999994?

Из заголовка C ++ 11 мне было интересно, если std::uniform_real_distribution<double> объект может выплюнуть двойное число больше 0.99999999999999994? Если это так, умножение этого значения на 2 будет равно 2.

Пример:

std::default_random_engine engine;
std::uniform_real_distribution<double> dist(0,1);

double num = dist(engine);

if (num > 0.99999999999999994)
num = 0.99999999999999994;

int test1 = (int)(0.99999999999999994 * 2);
int test2 = (int)(0.99999999999999995 * 2);

std::cout << test1 << std::endl; // 1
std::cout << test2 << std::endl; // 2

4

Решение

Максимальное значение dist(engine) в вашем коде можно вернуть std::nextafter(1, 0), Предполагая формат IEEE-754 для двоичного кода для doubleэто число

0.99999999999999988897769753748434595763683319091796875

Если ваш компилятор округляет литералы с плавающей точкой до ближайшего представимого значения, то это также значение, которое вы фактически получаете, когда пишете 0.99999999999999994 в коде (второе ближайшее представимое значение, конечно, 1).

8

Другие решения

std::uniform_real_distribution<double>(0, 1) должен вернуть значение, которое строго меньше, чем 1.0,

Однако то, что вы делаете с этим значением, зависит от множества сложностей операций с плавающей запятой, включая ошибки округления в вычислениях и выводе.

1

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector