Является ли это хорошим решением для жалобы R # на потерю точности?

#c# #double #resharper #mathematical-optimization #epsilon

#c# #двойной #resharper #математическая оптимизация #эпсилон

Вопрос:

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

 if (totValue != 1.0)
  

Resharper пожаловался на это, предложив мне использовать «EPSILON» и добавил именно такую константу в код (когда его пригласили сделать это). Однако он не создает саму константу и не указывает, какое значение она должна иметь. Это хорошее решение:

 const double EPSILON = double.Epsilon; // see http://msdn.microsoft.com/en-us/library/system.double.epsilon.aspx
. . .
if (Math.Abs(totValue - 1.0) > EPSILON)
    compValue = Convert.ToString(totValue*Convert.ToDouble(compValue));
  

?

Обновить

Я изменил его на это:

 const double EPSILON = 0.001;
  

… думая, что это, вероятно, достаточно велико и достаточно мало, чтобы работать с типичными двойными val (не научный материал, просто «у меня их 2,5» и т. Д.)

Ответ №1:

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

double.Epsilon это наименьшая возможная разница, которая может быть между любыми двумя двойниками. Для любых двух двойников невозможно быть ближе друг к другу, чем находясь double.Epsilon отдельно, поэтому единственный способ, чтобы эта проверка была верной, — это чтобы они были точно равны.

Что касается того, какое значение epsilon вы должны использовать на самом деле, это просто зависит, поэтому оно не генерируется для вас автоматически. Все зависит от того, какие типы операций вы выполняете с данными (что влияет на возможное отклонение от «истинного значения»), а также от того, насколько точность действительно важна в вашем приложении (и, конечно, если точность, о которой вы заботитесь, превышает вашу погрешность, у вас есть ошибка).проблема). Ваш epsilon должен иметь некоторое значение точности, превышающее (или равное) требуемую вам точность, при этом оно должно быть меньше возможной погрешности всех операций, выполняемых с любым числовым значением.

Комментарии:

1. Речь идет не о том, «насколько вы заботитесь о», а о том, «сколько ошибок вы ожидаете». Установка значения epsilon на то, насколько вам важно, может скрыть ошибки.

2. @alzaimar Эпсилон должен быть между ними , как я уже сказал в своем ответе. Вы не можете просто учитывать одно или другое. Если между ними нет пробела, то есть ваш предел погрешности превышает требуемую точность, тогда проблема неразрешима, и вам нужно либо уменьшить свой предел погрешности, либо работать с пониженной точностью.

Ответ №2:

ДА. Но еще лучше не использовать плавающую точку. Используйте decimal instad.

Однако, если по какой-то причине вы должны придерживаться double никогда не сравнивать напрямую, это означает, что никогда не полагайтесь, например a-b == 0 , на with ( a и b быть некоторыми double значениями, которые должны быть равны).

Арифметика с плавающей запятой выполняется быстро, но не точно, и с учетом этого R # является правильным.

Комментарии:

1. Используемое им значение epsilon не подходит по причинам, описанным в моем ответе.

2. Абсолютно правильно. Я сосредоточился на проблеме с плавающей запятой.