Что делает RemoveNoiseFromDoubleMath? - PullRequest
       1

Что делает RemoveNoiseFromDoubleMath?

1 голос
/ 22 октября 2010

В Silverlight Toolkit есть этот метод:

    /// <summary>
    /// Removes the noise from double math.
    /// </summary>
    /// <param name="value">The value.</param>
    /// <returns>A double without a noise.</returns>
    internal static double RemoveNoiseFromDoubleMath(double value)
    {
        if (value == 0.0 || Math.Abs((Math.Log10(Math.Abs(value)))) < 27)
        {
            return (double)((decimal)value);
        }
        return Double.Parse(value.ToString(CultureInfo.InvariantCulture), CultureInfo.InvariantCulture);
    }

Я не понимаю, какова цель, есть ли шум в парном разряде от математики в .Net?

Что происходит с двойным или десятичным удвоением?

Почему ToString выполняет синтаксический анализ?

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

Ответы [ 2 ]

1 голос
/ 22 октября 2010

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

Если вы, например, возьмете следующий фрагмент:

double result = 1.0 / 7.0;

double difference = result - RemoveNoiseFromDoubleMath(result);

Console.WriteLine(difference);

Это дает разницу -1,38777878078145E-16.

0 голосов
/ 22 октября 2010

Удивительно, что у этой функции есть блок комментариев, который фактически не объясняет, что это за «шум», с которым она пытается справиться, и как он влияет на значение.

То, как я это читаю, если число имеет менее 27 цифр от 10 до 10 (или равно нулю), оно преобразуется в десятичную, а затем обратно в двойную. Я ожидал бы, что преобразование в десятичное значение должно не повлиять на значение, поскольку десятичное разрешение имеет большее разрешение, чем двойное. Преобразование обратно в двойное число снова должно быть без потерь.

Пример Питера показывает, что эта операция действительно влияет на значение, поэтому, по-видимому, преобразования из двойного в десятичное и обратно не сохраняют значения, даже если они могут быть. Глядя в msdn, я вижу это: http://msdn.microsoft.com/en-us/library/yht2cx7b(v=VS.80).aspx

что говорит:

Когда вы конвертируете float или double в десятичное, исходное значение преобразуется в десятичном представлении и округлые на ближайший номер после 28 числа десятичное место, если требуется.

Ладно, значит, округляется. Это означает, что если у вас есть double со значением 1.9999999999999999999999999999, преобразование в десятичное число округлит его до 2, поэтому, когда оно конвертируется обратно в double, вы получаете double со значением точно 2.0.

Если число имеет более 27 цифр , оно преобразуется в строку, а затем анализируется. Я не уверен, каков будет конечный результат - это будет зависеть от поведения по умолчанию ToString и Double.parse.

...