Подтвердить что ты не робот

Где я могу найти epsilon машины в С#?

Эпсилон машины канонически определяется как наименьшее число, добавленное к одному, дает результат, отличный от одного.

Существует Double.Epsilon, но имя очень вводит в заблуждение: это наименьшее (денормализованное) значение Double, представляемое и, следовательно, бесполезное для любого типа числового программирования.

Я хотел бы получить истинный epsilon для типа Double, чтобы не иметь ограничений жесткого кода в моей программе. Как это сделать?

4b9b3361

Ответ 1

Это (на моей машине):

   1.11022302462516E-16

Вы можете легко вычислить его:

        double machEps = 1.0d;

        do {
           machEps /= 2.0d;
        }
        while ((double)(1.0 + machEps) != 1.0);

        Console.WriteLine( "Calculated machine epsilon: " + machEps );

Отредактировано:

Я вычислил 2 раза эпсилон, теперь это должно быть правильно.

Ответ 2

Библиотека Math.NET определяет Precision, который имеет свойство DoubleMachineEpsilon.

Вы можете проверить, как они это делают.

В соответствии с этим:

    /// <summary>
    /// The base number for binary values
    /// </summary>
    private const int BinaryBaseNumber = 2;

    /// <summary>
    /// The number of binary digits used to represent the binary number for a double precision floating
    /// point value. i.e. there are this many digits used to represent the
    /// actual number, where in a number as: 0.134556 * 10^5 the digits are 0.134556 and the exponent is 5.
    /// </summary>
    private const int DoublePrecision = 53;

    private static readonly double doubleMachinePrecision = Math.Pow(BinaryBaseNumber, -DoublePrecision);

Таким образом, это 1,11022302462516E-16 в соответствии с этим источником.

Ответ 3

Просто скорректируйте значение:

const double e1 = 2.2204460492503131e-16;

или используйте силу двух:

static readonly double e2 = Math.Pow(2, -52);

или используйте свое определение (более или менее):

static readonly double e3 = BitConverter.Int64BitsToDouble(BitConverter.DoubleToInt64Bits(1.0) + 1L) - 1.0;

И посмотрите Википедия: машина epsilon.

Ответ 4

Ref. рутина в Meonester's: Фактически значение machEps при выходе из цикла do... while таково, что 1 + machEps == 1. Чтобы получить эпсилон машины, мы должны вернуться к предыдущему значению, добавив следующее после цикла: machEps * = 2.0D; Это вернет 2.2204460492503131e-16 в соответствии с рекомендацией в документации Microsoft для Double.Epsilon.