2016-06-20 4 views
1

Мне нужно написать функцию для сравнения строкового значения «15.0000000000000001» до «15», и я использую MathNet. Использование MathNet.Symbolics.Expression.Real принимает только double. Когда я делаю следующееMathNet real double precision issue

Expression valOne = Expression.Real(Double.Parse("15.0000000000000001")); 
Expression valTwo = Expression.Real(Double.Parse("15")); 

valOne.Equals(valTwo); 

Вышеприведенные имеет значение true.Double.Parse 15.0000000000000001 возвращается 15. Я понимаю, что 0 после десятичной бессмысленно удваивать и имеет ограничения на хранение.

Не могли бы вы помочь?

+0

Какие вычисления или сравнения вы делаете, где вам нужно 18 цифр абсолютной точности? –

+0

Чтобы представить это в перспективе - есть [приблизительно 7.5e18 зерен песка на земле] (http://www.npr.org/sections/krulwich/2012/09/17/161096233). Это действительно имеет значение, если вы ошибаетесь на десять зерен? –

ответ

2

Как правило, поплавок может содержать до 14 смежных цифр, а также мощность 10. Так, например, он будет хранить 12.3456789как 1.23456789с мощностью 1: несколько двух чисел вместе, и вы получите сохраненный номер.

В вашем примере у вас есть пробел в 18 цифр от первого 1 до последнего 1. Float не может сохранить это в доступном пространстве, поэтому он отбрасывает младшие значащие бит - в этом случае конечный 1. Это два номера в вашем примере должны совпадать.

Однако, если вы сравните 12.3456789по 12.3456789, тогда не были бы равными.

Обратите внимание, что 14 десятичных цифр, о которых я упоминаю, являются эмпирическим правилом. В зависимости от значения этих цифр это может быть меньше.

И да: это означает, что поплавки не являются точными, они являются приблизительными.

 Смежные вопросы

  • Нет связанных вопросов^_^