2010-09-22 5 views
10

Я имею г ++ 4.4.3 на Linux с Ubuntu Lucid Lynx, и я получаю:Получение отрицательного NaN на g ++ 4.4.3, является ли это стандартом?

-nan

в результате. На Hardy Heron с г ++ 4.3.1, я получаю все

нана

Это вызывает мой текст дифф регресс на неудачу, так как я использую COUT напечатать этот числовой результат.

В чем смысл подписанного nan, и есть ли способ сказать компилятору, что unsigned nan достаточно?

+0

Что расчет вы делаете, что приводит к такому значению ? –

+0

Что вы подразумеваете под «подписанным наном»? Вы имеете в виду отрицательный? Внимательно просмотрев статью Википедии, NaNs явно подписаны. –

+4

«cout << 0./0. << endl» результаты «-nan» на всех моих Ubuntu Lucid Lynx Systems и «nan» на Mac OS X Snow Leopard и Ubuntu Hardy Heron. Это все системы x86_64. – Juan

ответ

8

Вы может получить подписанную NaN, поскольку NaN-Несс величины и знак значений контролируются различными битами в IEEE754 (NaN просто обозначена специальными значения экспонентов, отличных от знакового бита). Я не понимаю, что это за операция.

Это возможно, что один из обычных операций, которые производят NaN может быть причиной отрицательного изменения (например, +0/-0 или +Inf/-Inf). Но я бы подумал, что NaN будут печатать как nan независимо от знака.

Однако, хотя стандарт подробно описывает, как обрабатываются номера, странно молчит о том, как они печатаются. В Wikipedia page for NaN перечислены эти:

nan   NaN   NaN%  NAN   NaNQ 
NaNS  qNaN  sNaN  1.#SNAN  1.#QNAN 
-1.#IND  -NaN  NaN12345 -sNaN12300 

с некоторыми из тех, кто показывает знак и дополнительной полезной нагрузки.

Обратите внимание, что я говорю о стандартах IEEE. Стандарты ISO C указывают на ограниченное количество форм, но независимо от того, печатается ли знак и/или полезная нагрузка, зависит от реализации. Я могу только предположить, что более поздние версии библиотеки изменили свое поведение.

Как исправить это в компиляторе, я не уверен. Я бы просто взял прагматичный подход и запустил выходной файл через что-то вроде sed 's/-nan/nan/g'. Надеюсь, это не вызовет других проблем.

И вы также должны следить за формой, которая также позволяет печатать полезную нагрузку, хотя я бы только беспокоился об этом, когда тесты снова начнут сбой. Но я бы добавил комментарий около этой команды sed, указывающий, что это может произойти в будущем. Таким образом, по крайней мере, тот, кто следует за вами, поймет, почему.

+0

Я могу отфильтровать результат, но я просто хочу убедиться, что мои рассуждения законны, когда кто-то видит фильтрацию. – Juan

+0

Стандарт сам определяет его как NaN, когда показатель экспоненты является максимальным значением, а мантисса имеет определенный формат. Знак не входит в него. Я бы просто описал это на упрощенной процедуре вывода, которая проверила знак независимо от того, выводит ли он реальные числа или одно из специальных. – paxdiablo

2

Подписанный NaN возможен, хотя я не знаю достаточно о плавающей точке, чтобы знать, почему одна платформа будет производить -NaN, а другая будет производить NaN. Но так как NaN имеет некоторые необычные поведения, я действительно не удивлен, что это может произойти.

Вот фрагмент из описания документа C99 для отформатированных с плавающей точкой ввода/вывода:

Двойной аргумент, представляющий NaN преобразуется в одном из стилей [-] NaN или [-] NaN (n-char-sequence) - , который является стилем и значением любой последовательности n-char- , является реализацией.F спецификатор преобразования

Вы можете использовать copysign(), чтобы получить знак значения NaN. Пример из документа C99:

if (isnan(c)) c = copysign(0.0, c); 

Но as paxdiablo indicated, было бы легче, чтобы обеспечить результат «-nan» в тестовых сценариях.

13

Изменение поведения может быть связано с библиотеками, а не с компилятором. Существует, конечно, изменение Glibc вокруг правильного вида времени - от входа для 2009-08-23 в строке 2528 в ChangeLog.17 в источнике GLibC:

... 
    * stdio-common/printf_fp.c: ISO C expects to print the sign of NaN 
    as well. 
... 
+1

Невероятная находка. Точная же бинарная копия, скопированная на новую машину, приводит к -nan. Отличная работа! – Juan

+2

Собственно, ISO C _doesn't_ ожидает печати знака, он оставлен как зависящий от реализации. Не позволяйте мне отвлекаться от вашего ответа, хотя это была хорошая находка, и, несомненно, причина, по которой изменилось поведение. – paxdiablo

+0

Мэтью Слейтер Как вам удалось найти ту линию, которая была совершенно неразборчива? – Bilow

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