Правильный способ сравнения системы.Удвоить до ' 0 ' (число, int?)
извините, это может быть простой глупый вопрос, но мне нужно знать, чтобы быть уверенным.
у меня есть это if
выражение
void Foo()
{
System.Double something = GetSomething();
if (something == 0) //Comparison of floating point numbers with equality
// operator. Possible loss of precision while rounding value
{}
}
это выражение равно
void Foo()
{
System.Double something = GetSomething();
if (something < 1)
{}
}
? Потому что тогда у меня может возникнуть проблема, введя if
например, со значением 0,9.
5 ответов:
Ну, как близко вам нужно значение, чтобы быть 0? Если вы пройдете через множество операций с плавающей запятой, которые в "бесконечной точности" могут привести к 0, вы можете получить результат "очень близко" к 0.
обычно в этой ситуации вы хотите предоставить какой-то Эпсилон и проверить, что результат находится именно в этом Эпсилоне:
if (Math.Abs(something) < 0.001)
Эпсилон, который вы должны использовать, зависит от приложения-это зависит от того, что вы делаете.
конечно, если результат должен быть ровно ноль, тогда простая проверка равенства в порядке.
Если
something
был назначен из результата операции, отличной отsomething = 0
тогда вам лучше использовать:if(Math.Abs(something) < Double.Epsilon) { //do something }
Edit: этот код неверен. Эпсилон-это наименьшее число, но не совсем ноль. Когда вы хотите сравнить число с другим числом, вам нужно подумать о том, что такое приемлемый допуск. Допустим, что-нибудь за ее пределами .00001 тебя это не волнует. Это номер, который вы бы использовали. Значение зависит от домена. Тем не менее, это в основном конечно, никогда не удваивается.Ипсилон.
код
something
- этоdouble
, а вы правильно определили, что в строкеif (something == 0)
у нас есть
double
на левой стороне (lhs) иint
на правой стороне (rhs).но теперь кажется, что вы думаете, что lhs будет преобразован в
int
, а потом==
знак будет сравнивать два целых числа. Это не что происходит. Преобразование Сdouble
доint
is явно и не может произойти "автоматически".вместо этого происходит обратное. РГО превращается в
double
, а потом==
знак становится тестом равенства между двумя двойниками. Это преобразование является неявным (автоматическим).считается лучше (некоторыми) писать
if (something == 0.0)
или
if (something == 0d)
потому что тогда это, что вы сравниваете два двухместных. Однако, это всего лишь вопрос стиля и читабельность, потому что компилятор будет делать то же самое в любом случае.
в некоторых случаях также уместно ввести "толерантность", как в ответе Джона Скита, но эта толерантность будет
double
тоже. Это может конечно1.0
если вы хотите, но это не должно быть [наименее строго положительное] целое число.
Если вы просто хотите подавить предупреждение, сделайте следующее:
if (something.Equals(0.0))
конечно, это только правильное решение, если вы знаете, что дрифт-это не проблема. Я часто делаю это, чтобы проверить, если я собираюсь делить на ноль.
Я не думаю, что это все равно, если честно. Рассмотрим ваш собственный пример: something = 0.9, или 0.0004. В первом случае оно будет ложным, во втором-истинным. Имея дело с этими типами, я обычно определяю для себя процент точности и сравниваю в пределах этой точности. Зависит от ваших потребностей. что-то вроде...
if(((int)(something*100)) == 0) { //do something }
надеюсь, что это помогает.