Где мне найти машину эпсилон в C #? - PullRequest
14 голосов
/ 22 февраля 2012

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

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

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

Ответы [ 4 ]

8 голосов
/ 22 февраля 2012

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

   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 раза эпсилон, теперь должно быть правильно.

7 голосов
/ 22 февраля 2012

Библиотека 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 согласно этому источнику.

1 голос
/ 08 мая 2016

Просто жестко введите значение:

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;

И см. Википедия: Эпсилон машины .

0 голосов
/ 09 марта 2017

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

...