Действительно ли безопасно проверить значения с плавающей точкой на равенство 0?

Закрыть. Вам нужно присоединиться к подзапросу на дату!

(SELECT patient_id, max(dispensing_date) as max_dispensing_date
 FROM `v_patient_visits`
 GROUP BY patient_id
) visits 
ON visits.patient_visit_id = pv.patient_visit_id AND
   visits.max_dispensing_date = pv.dispensing_date
97
задан Daniel Daranas 21 February 2016 в 12:38
поделиться

6 ответов

Это безопасно , чтобы ожидать, что сравнение возвратится true, если и только если двойная переменная имеет значение точно 0.0 (который в Вашем исходном фрагменте кода является, конечно, случаем). Это согласовывается с семантикой == оператор. a == b средство" a равно b".

Это не безопасно (потому что это не, исправляют ) ожидать, что результатом некоторого вычисления будет нуль в двойном (или в более общем плане, плавающая точка) арифметика каждый раз, когда результатом того же вычисления в чистой математике является нуль. Это вызвано тем, что, когда вычисления въезжают в землю, ошибка точности с плавающей точкой появляется - понятие, которое не существует в арифметике Вещественного числа в Математике.

113
ответ дан Daniel Daranas 24 November 2019 в 05:25
поделиться

Если необходимо сделать много сравнений "равенства", это могла бы быть хорошая идея записать немного функции помощника или дополнительного метода в.NET 3.5 для сравнения:

public static bool AlmostEquals(this double double1, double double2, double precision)
{
    return (Math.Abs(double1 - double2) <= precision);
}

Это могло использоваться следующий путь:

double d1 = 10.0 * .1;
bool equals = d1.AlmostEquals(0.0, 0.0000001);
50
ответ дан Dirk Vollmar 24 November 2019 в 05:25
поделиться

Для Вашей простой выборки тот тест хорошо. Но что относительно этого:

bool b = ( 10.0 * .1 - 1.0 == 0.0 );

Помнят, что.1 периодическая десятичная дробь в двоичном файле и не может быть представлена точно. Затем сравните это с этим кодом:

double d1 = 10.0 * .1; // make sure the compiler hasn't optimized the .1 issue away
bool b = ( d1 - 1.0 == 0.0 );

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

15
ответ дан Joel Coehoorn 24 November 2019 в 05:25
поделиться

От записи MSDN для Дважды. Равняется :

Точность в Сравнениях

Равняется методу, должен использоваться с осторожностью, потому что две по-видимому эквивалентных стоимости могут быть неравными из-за отличающейся точности двух значений. Следующий пример сообщает, что Двойное значение.3333 и Двойное, возвращенное путем деления 1 на 3, неравны.

...

Вместо того, чтобы выдержать сравнение для равенства, одна рекомендуемая техника включает определение приемлемого поля различия между двумя значениями (такими как.01% одного из значений). Если абсолютное значение различия между двумя значениями будет меньше чем или равно тому полю, то различие, вероятно, произойдет из-за различий в точности и, поэтому, значения, вероятно, будут равны. Следующий пример использует эту технику для сравнения.33333 и 1/3, два Двойных значения, которые предыдущий пример кода нашел, чтобы быть неравным.

кроме того, см. Дважды. Эпсилон .

13
ответ дан Stu Mackellar 24 November 2019 в 05:25
поделиться

Если число было непосредственно присвоено плаванию, или дважды затем безопасно протестировать против нуля или любого целого числа, которое может быть представлено в 53 битах для двойного или 24 битах для плавания.

Или помещать его иначе можно всегда присваиваться и целочисленное значение к двойному и затем сравнивать загибание с тем же целым числом и гарантироваться, это будет равно.

можно также начать путем присваивания целого номера и иметь простые сравнения, продолжают работать путем придерживания добавления, вычитания или умножения на целые числа (предполагающий, что результат составляет меньше чем 24 бита для плавания abd 53 бита для двойного). Таким образом, Вы можете рассматривать плавания и удваиваетесь как целые числа при определенных управляемых условиях.

3
ответ дан Kevin Gale 24 November 2019 в 05:25
поделиться

Нет, все не в порядке. Так называемые денормализованные значения (субнормальные), при сравнении равные 0,0, сравниваются как ложные (ненулевые), но при использовании в уравнении нормализуются (становятся 0,0). Таким образом, использование этого в качестве механизма, позволяющего избежать деления на ноль, небезопасно. Вместо этого добавьте 1.0 и сравните с 1.0. Это гарантирует, что все субнормалы будут рассматриваться как ноль.

2
ответ дан 24 November 2019 в 05:25
поделиться
Другие вопросы по тегам:

Похожие вопросы: