Может ли число с плавающей запятой IEEE-754 <1 (т. Е. Созданное с помощью генератора случайных чисел, который генерирует число> = 0,0 и <1,0) когда-либо умножаться на некоторое целое число (в форме с плавающей запятой), чтобы получить число, равное или большее, чем что целое число из-за округления?
т.е.
double r = random() ; // generates a floating point number in [0, 1)
double n = some_int ;
if (n * r >= n) {
print 'Rounding Happened' ;
}
Это может быть эквивалентно утверждению, что существуют N и R, такие, что если R является наибольшим числом, меньшим 1, которое может быть представлено в IEEE-754, то N * R> = N (где * и> = являются подходящими IEEE- 754 оператора)
Это вытекает из этого вопроса, основанного на этой документации и случайной функции postgresql
Ответы:
Предполагая округление до ближайшего и что , тогда всегда. (Будьте осторожны, чтобы не преобразовать слишком большое целое число.)N ∗ R < NN>0 N∗R<N
Пусть , где - значение, а - целое число. Пусть и получим оценкуc ∈ [ 1 , 2 ) q 1 - 2 - s = Rc2−q=N c∈[1,2) q 1−2−s=R
с равенством тогда и только тогда, когда . Правая часть меньше и, поскольку - это точно единицы в последнем месте , либо и является точно представимым (поскольку является нормальным, а не наименьшим нормальным), или , а ближайшее округление направлено вниз. В обоих случаях, меньше , чем .c=1 N 2−q−s 0.5 N c=1 2−q−2−q−s N c>1 N∗R N
Округление вверх может вызвать проблему, а не то, что его следует выбирать в присутствии ничего не подозревающих пользователей. Вот какой-то С99, который печатает
"0\n1\n"
на моей машине.источник