Какое значение с плавающей запятой заставляет sprintf_s () выдавать "1. # QO"? - PullRequest
18 голосов
/ 09 мая 2011

У меня есть некоторый (унаследованный встроенный c) код, который создает файл .csv с помощью некоторых вызовов sprintf.Изредка вижу значения 1.#QO.Я пытался воспроизвести эти значения с условиями, которые должны давать отрицательную бесконечность, положительную бесконечность и NaN, но ни одно из них, похоже, не дает мне волшебный 1.#QO результат.Так что же дает это значение?

... и да, я знаю, что в математических вычислениях, производящих это значение, очевидно, что-то идет не так, но понимание того, что это значит, поможет в отладке.

[Редактировать 1] Фактическая строка, которая выполняет преобразование:

sprintf_s(txt, CSV_HEADER_SIZE, "%.3f", value);

где:

#define CSV_HEADER_SIZE (100)
char txt[CSV_HEADER_SIZE];

Я компилирую с MS VisualStudio 2008.

[Редактировать 2] Немного больше копаний показывает 0xFFFFFFFF дает -1.#QO:

unsigned int i = 0xFFFFFFFF;
float* f = (float*)&i;
printf("%.3f", *f); // gives -1.#QO

.. и смотрит на это в VisualStudio отладчик расширяет его до -1.#QNAN00, так что похоже, что это, вероятно, специфичное для Microsoft представление NaN?

Ответы [ 4 ]

11 голосов
/ 10 мая 2011

"- 1. # QO" равно "-1. # QNAN" после "округления" для 3 знаков после запятой. N округляет до O как «A»> = «5» и «N» + 1 == «O».

По этой же причине ваш отладчик показывает «-1. # QNAN00», поскольку он печатает с 7 местами и добавляет в конец нули заполнения.

QNaN - это тихий NaN .

2 голосов
/ 10 мая 2011

После долгих раздумий я могу окончательно сказать, что установка 4-байтового плавающего числа в 0x7FFFFFFF и передача его в sprintf_s со спецификатором формата %.3f - вот что дало мне 1.#QO:

const int bufSize = 100;
char buf[bufSize];
unsigned int i;
float* f = (float*)&i;
int retval;

i = 0xFFFFFFFF;
retval = sprintf_s(buf, bufSize, "%.3f\n", *f);
printf("sprintf_s returned %d, converted val = %s", retval, buf); // == sprintf_s returned 7, converted val = -1.#QO
retval = sprintf_s(buf, bufSize, "%f\n", *f);
printf("sprintf_s returned %d, converted val = %s", retval, buf); // == sprintf_s returned 10, converted val = -1.#QNAN0

i = 0x7FFFFFFF;
retval = sprintf_s(buf, bufSize, "%.3f\n", *f);
printf("sprintf_s returned %d, converted val = %s", retval, buf); // == sprintf_s returned 6, converted val = 1.#QO
retval = sprintf_s(buf, bufSize, "%f\n", *f);
printf("sprintf_s returned %d, converted val = %s", retval, buf); // == sprintf_s returned 9, converted val = 1.#QNAN0

... кажется, что спецификатор формата %.3f обрезал результат NAN, поэтому то, что должно было быть 1.#QNAN0, было сокращено до 1.#QO.

1 голос
/ 09 мая 2011

Проверяли ли вы, что sprintf_s () вернул ошибку?Если это так, вы не должны использовать результат.Поскольку код выглядит не так, как вы проверили, я думаю, вы должны сделать эту проверку.Фактически, если вы не протестируете результат одной из функций *_s(), у вас возникнут проблемы.

1 голос
/ 09 мая 2011

Немного погуглив, указывает на ошибку деления на 0.Хотя я бы ожидал чего-то другого, если бы это было так.Тем не менее, похоже, что это характерно для MS / Visual C.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...