Общеизвестно, что при сравнении значений с плавающей запятой нужно быть осторожным. Обычно вместо использования ==
мы используем тестирование на основе равенства epsilon или ULP.
Однако, интересно, есть ли случаи, когда использование ==
отлично?
Посмотрите на этот простой фрагмент, какие случаи гарантированно преуспеют?
void fn(float a, float b) {
float l1 = a/b;
float l2 = a/b;
if (l1==l1) { } // case a)
if (l1==l2) { } // case b)
if (l1==a/b) { } // case c)
if (l1==5.0f/3.0f) { } // case d)
}
int main() {
fn(5.0f, 3.0f);
}
Примечание. Я проверил это и это, но они не охватывают (все) мои дела.
Примечание2: Кажется, что я должен добавить дополнительную информацию, поэтому ответы могут быть полезны на практике: я хотел бы знать:
- что говорит стандарт C++
- что произойдет, если реализация C++ следует за IEEE-754
Это единственное релевантное выражение, которое я нашел в текущем проекте стандарта:
Представление значений типов с плавающей точкой - это реализация -d. [Примечание: в этом документе нет требований к точности операций с плавающей запятой; см. также [support.limits]. - конечная нота]
Таким образом, означает ли это, что даже "случай a" - это реализация? Я имею в виду, что l1==l1
определенно является операцией с плавающей запятой. Итак, если реализация "неточна", то может ли l1==l1
быть ложным?
Я думаю, что этот вопрос не является дубликатом. С плавающей точкой == когда-либо ОК? , Этот вопрос не касается ни одного из случаев, о которых я прошу. Тот же предмет, другой вопрос. Я хотел бы получить ответы конкретно на случай a) -d), для которого я не могу найти ответы в дублированном вопросе.