У меня есть следующий код:
double x = 0;
{ ...do stuff ...}
if(x == 0){
}
Мне всегда учили, что вы не должны проверять float для равенства. Проверяет, равна ли она нулю любой другой?
У меня есть следующий код:
double x = 0;
{ ...do stuff ...}
if(x == 0){
}
Мне всегда учили, что вы не должны проверять float для равенства. Проверяет, равна ли она нулю любой другой?
Причина, по которой вы не должны проверять float для равенства, состоит в том, что числа с плавающей запятой не совсем точны - есть некоторая неточность в хранении с некоторыми числами, например те, которые слишком далеко продвинулись в мантисса и повторяют десятичные знаки (обратите внимание, что я Я говорю о повторении десятичных знаков в базе 2). Вы можете представить себе эту неточность как "округление". Цифры, которые выходят за пределы точности числа с плавающей запятой, усекаются, эффективно округляя вниз.
Если он не изменился, он сохранит это равенство. Однако, если вы измените его даже немного, вы, вероятно, не должны использовать равенства, а вместо этого диапазон, как (x < 0.0001 && x > -.0001)
.
Короче: до тех пор, пока вы не играете с x на очень маленьком уровне, это нормально.
Безопасно, если 0, который вы пытаетесь поймать, является исходным значением 0 при инициализации. Тем не менее, это небезопасно, если вы ожидаете 0 от математической операции.
Вы по-прежнему не должны проверять, равна ли оно нулю. Просто проверьте, не близится ли он к нулю.
private final static double EPSILON = 0.00001;
if (x + EPSILON > 0 && x - EPSILON < 0){
...
}
если вы сами установили его и хотите увидеть, если он когда-либо изменился, вы можете безопасно проверить равенство (например, использовать значение дозорного), хотя NaN безопаснее для таких вещей
float x=Float.NaN;
{
//some code that may or may not set x
}
if(Float.isNaN(x))//it never got set
double имеет положительный и отрицательный нуль. ==
между положительным нулем и отрицательным нулем возвращает false. Кроме того, ==
betwen два NaNs возвращают false.