2016-05-18 6 views
1

Сравнение с плавающей запятой по умолчанию (например, 3.0 < 5.0) в C упорядочено, то есть результат false, если один из аргументов NaN. Однако компиляторы и процессоры также имеют неупорядоченные сравнения. Например, в LLVM IR fcmp instruction имеют упорядоченные и неупорядоченные варианты. C99 имеет некоторые функции для проверки NaN. Однако, кроме этого, я не нашел других неупорядоченных операций сравнения. Существуют ли какие-либо расширения GNU (или другие стандартные библиотечные функции), которые предлагают неупорядоченные сравнения с плавающей запятой?Неупорядоченные сравнения с плавающей запятой в C

До сих пор я мог реализовать их только путем проверки на противоположное условие. Например, чтобы реализовать неупорядоченное сравнение a >= b, я вместо этого написал упорядоченный !(a < b), который LLVM в конечном итоге упрощает к неупорядоченному сравнению fcmp uge double %1, %2.

+0

[hm] (http://www.gnu.org/software/libc/manual/html_node/FP-Comparison-Functions.html)? –

+3

Вы немного перепутали терминологию здесь. Это не вопрос «упорядоченных» или «неупорядоченных» версий сравнений. Ключевые слова 'fcmp', такие как' guge', означают «неупорядоченные * или * больше или равно», а не «неупорядоченное» сравнение больше или равно.Вызов этой «неупорядоченной» версии> = аналогичен вызову> = «равной» версии>. – user2357112

+0

C99 также имеет 'isunordered (x, y)' – ninjalj

ответ

3

Однако, кроме этого, я не нашел других неупорядоченных операций сравнения. Существуют ли какие-либо расширения GNU (или другие стандартные библиотечные функции), которые предлагают неупорядоченные сравнения с плавающей запятой?

Как @ user2357112, наблюдаемый в комментариях, «неупорядоченные сравнения с плавающей запятой» - это не вещь. Этот термин даже не имеет смысла. То, что вы, по-видимому, хотите оценить, - это предикаты формы «x меньше y или два являются неупорядоченными».

Соответствующие реализации C не могут добавлять операторов, даже в качестве расширений. Они могут в принципе определять дополнительные значения для существующих операторов, но я не знаю никакой реализации, которая обеспечивает конкретные операции, которые вы ищете именно таким образом. Как вы уже выяснили, довольно сложно использовать существующих операторов C для этой цели:

До сих пор я мог реализовывать их только путем проверки на противоположное условие. Например, для реализации неупорядоченного a >= b сравнения, вместо этого я написал упорядоченную !(a < b)

Update: Проблема в том, что эти сравнения будут поднимать исключение с плавающей точкой, когда один из операндов является NaN (и Исключения FP не отключены). Но тебе повезло! С C99 есть standard macros implementing the comparisons you seek. Они гарантированно оценивают свои аргументы только один раз, и они не вызывают исключения с плавающей запятой.

И, конечно же, если вы хотите, чтобы иметь возможность более четко в вашем коде, который вы явно вмещающей пренебрежимо малых выразить, то вы всегда можете писать макросы для него:

#define GE_OR_UNORDERED(x, y) (!((x) < (y))) 

// ... 

if (GE_OR_UNORDERED(a, b)) // ... 

Заметим также, что все Это в значительной степени зависит от деталей реализации. Хотя C распознает возможность , что реальные типы могут принимать значения, такие как NaN, которые не представляют числа с плавающей запятой, они не требуют от них этого и не определяют поведение реляционных или арифметических операций с такими значениями , Хотя в большинстве реализаций в наши дни используются форматы и операции с плавающей запятой IEEE-754, они не обязаны это делать, а исторически некоторые из них не имеют.

+0

Да, я согласен с тем, что я должен был придумать лучшее имя. Как бы вы обращали внимание на то, что я назвал упорядоченными и неупорядоченными сравнениями с плавающей запятой, например, чтобы различать два класса LLVM IR с плавающей запятой (http://llvm.org/docs/LangRef.html#fcmp-instruction)? Кроме того, не редкость, что расширения GNU C предоставляют некоторую функциональность, которую нет в стандарте C. Например, он также имеет некоторые макросы, опубликованные @Eugene Sh. выше, чтобы обеспечить некоторое гарантированное поведение для случаев, когда стандарт C оставляет неопределенным. – box

+1

@box: Эти макросы являются частью стандарта, а не расширения. – user2357112