Этот вопрос касается порога, при котором Math.Floor(double)
и Math.Ceiling(double)
решают дать вам предыдущее или следующее целочисленное значение. Меня беспокоило, что порог, похоже, не имеет ничего общего с Double.Epsilon
, который является наименьшим значением, которое может быть представлено двойным. Например:
double x = 3.0;
Console.WriteLine( Math.Floor( x - Double.Epsilon ) ); // expected 2, got 3
Console.WriteLine( Math.Ceiling( x + Double.Epsilon) ); // expected 4, got 3
Даже умножение Double.Epsilon
на справедливый бит не помогло:
Console.WriteLine( Math.Floor( x - Double.Epsilon*1000 ) ); // expected 2, got 3
Console.WriteLine( Math.Ceiling( x + Double.Epsilon*1000) ); // expected 4, got 3
С некоторыми экспериментами я смог определить, что порог где-то около 2.2E-16, что очень мало, но VASTLY больше, чем Double.Epsilon
.
Причина этого вопроса в том, что я пытался вычислить число цифр в числе с помощью формулы var digits = Math.Floor( Math.Log( n, 10 ) ) + 1
. Эта формула не работает для n=1000
(которую я случайно наткнулся случайно), потому что Math.Log( 1000, 10 )
возвращает число, равное 4.44E-16 от его фактического значения. (Позже я обнаружил, что встроенный Math.Log10(double)
обеспечивает гораздо более точные результаты.)
Если порог не должен быть привязан к Double.Epsilon
или, если нет, не должен быть документирован порог (я не мог найти упоминания об этом в официальной документации MSDN)?