Подтвердить что ты не робот

Является ли проверка двойного равенства безопасным?

У меня есть следующий код:

double x = 0;

{ ...do stuff ...}

if(x == 0){

}

Мне всегда учили, что вы не должны проверять float для равенства. Проверяет, равна ли она нулю любой другой?

4b9b3361

Ответ 1

Причина, по которой вы не должны проверять float для равенства, состоит в том, что числа с плавающей запятой не совсем точны - есть некоторая неточность в хранении с некоторыми числами, например те, которые слишком далеко продвинулись в мантисса и повторяют десятичные знаки (обратите внимание, что я Я говорю о повторении десятичных знаков в базе 2). Вы можете представить себе эту неточность как "округление". Цифры, которые выходят за пределы точности числа с плавающей запятой, усекаются, эффективно округляя вниз.

Если он не изменился, он сохранит это равенство. Однако, если вы измените его даже немного, вы, вероятно, не должны использовать равенства, а вместо этого диапазон, как (x < 0.0001 && x > -.0001).

Короче: до тех пор, пока вы не играете с x на очень маленьком уровне, это нормально.

Ответ 2

Безопасно, если 0, который вы пытаетесь поймать, является исходным значением 0 при инициализации. Тем не менее, это небезопасно, если вы ожидаете 0 от математической операции.

Ответ 3

Вы по-прежнему не должны проверять, равна ли оно нулю. Просто проверьте, не близится ли он к нулю.

private final static double EPSILON = 0.00001;
if (x + EPSILON > 0 && x - EPSILON < 0){
...
}

Ответ 4

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

float x=Float.NaN;
{
   //some code that may or may not set x
}
if(Float.isNaN(x))//it never got set

Ответ 5

double имеет положительный и отрицательный нуль. == между положительным нулем и отрицательным нулем возвращает false. Кроме того, == betwen два NaNs возвращают false.