2013-09-06 7 views
1

Используется для сравнения плавающей запятой со следующей функцией. Однако я просто проверяю, что C++ 11 предоставляет некоторую функцию сравнения с плавающей запятой, такую ​​как isgreaterequal. Мой вопрос: должен ли я заменить его на функции в стандарте?сравнение с плавающей запятой в C++ 11

bool isEqual(double lhs, double rhs, double epsilon = /std::numeric_limits<double>::epsilon()) 
{ 
    if (lhs == rhs) 
    { 
     return true; 
    } 

    return fabs(lhs - rhs) <= ((fabs(lhs) > fabs(rhs) ? fabs(rhs) : fabs(lhs)) * epsilon); 
} 
+1

Это не правильный способ сравнения чисел с плавающей запятой. Во-первых, он уменьшает ложные негативы за счет увеличения ложных срабатываний. Во-вторых, при отсутствии конкретных знаний о предыдущих вычислениях нет причин ожидать, что ошибка будет пропорциональна левой. В-третьих, один эпсилон ошибки необычен для любых, но простейших вычислений. В-четвертых, существует огромный разрыв в допуске ошибок; когда 'lhs' падает ниже' rhs', допуск переходит от почти 'rhs * epsilon' к' rhs', что составляет примерно 2 ** 52. –

+0

@EricPostpischil 1. Такова арифметика с конечной точностью. 2-3. Следовательно, 'epsilon' является переменным аргументом. 4. Проверьте parens; меньший из 'lhs' или' rhs' умножается на 'epsilon'. – Potatoswatter

+1

@Potatoswatter: Вы правы относительно 4. 1: Тот факт, что точность конечна, не делает это правильным. Следует использовать другие подходы. 2: Передача значения epsilon, отличного от значения по умолчанию, не изменяет того факта, что он умножается пропорционально сравниваемым значениям. 3: По умолчанию слишком мало. –

ответ

1

По: cplusplus.com

Использование isgreaterequal, если либо аргументы NaN, то сравнение оценивается как ложное.

Использование >=, если любые аргументы NaN, то исключение FE_INVALID будет поднято.

Итак, я думаю, вы должны сохранить свою функцию так, как она есть, поскольку вы, вероятно, хотели бы знать, был ли один из ваших аргументов NaN.

From C11 Draft N1570:
p.516 Раздел F.9.3 Операторы отношения

< х у → isless (х, у) (и аналогично для ≤,>, ≥) Хотя численно равна , эти выражения не эквивалентны из-за побочных эффектов , когда x или y является NaN, а состояние праймы FENV_ACCESS равно '' on ''. Это преобразование, которое было бы желательно, если бы потребовался дополнительный код , чтобы вызвать «недействительное» исключение с плавающей запятой для неустановленных случаев , может быть выполнено, если состояние FENV_ACCESS прагма «выключено».

+0

Спецификация для 'isgreaterequal' и др. Говорит о том, что' FE_INVALID' поднят '> =', но это не то место, где указано '> ='. По моему опыту, на Intel 'FE_INVALID' никогда не получается из NaN, но я не вижу, где C даже указывает, что он может быть поднят. В лучшем случае зависимость от сопоставлений сигнализации неспортивна. – Potatoswatter

+0

Я верю, где вы читаете документацию? –

+0

[gnu.org] (http://www.gnu.org/software/libc/manual/html_node/FP-Comparison-Functions.html#FP-Comparison-Functions) показывает то же самое, но я собираюсь испытайте это. –

Смежные вопросы