我有一些(遗留嵌入式c)代码,它通过一些sprintf
调用生成.csv文件。偶尔我会看到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 Visual Studio 2008进行编译。
[编辑2] 更多挖掘展示0xFFFFFFFF
给出了-1.#QO
:
unsigned int i = 0xFFFFFFFF;
float* f = (float*)&i;
printf("%.3f", *f); // gives -1.#QO
..并在Visual Studio调试器中查看它,将其扩展为-1.#QNAN00
所以看起来这可能是Microsoft特定于NaN
的表示形式?
答案 0 :(得分:11)
“ - 1.#QO”在小数点后“舍入”3位后为“-1。#QNAN”。 N轮到O为'A'> ='5'和'N'+ 1 =='O'。
这与你的调试器显示“-1。#QNAN00”的原因类似,因为它打印了7个位置并在末尾添加了填充零。
QNaN是quiet NaN。
答案 1 :(得分:2)
经过大量的摆弄后,我可以确定地说,设置一个4字节的浮动到0x7FFFFFFF
并将其传递给sprintf_s
,格式说明符为%.3f
,这就是我{ {1}}:
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
格式说明符正在裁剪NAN结果,因此本应将%.3f
切割为1.#QNAN0
。
答案 2 :(得分:1)
一个小的谷歌搜索指向除以0错误。虽然如果是这样的话,我会期待一些不同的东西。也就是说,它似乎是MS / Visual C特有的。
答案 3 :(得分:1)
您是否检查过sprintf_s()是否返回了失败?如果是,则不应使用结果。由于代码看起来不像你检查过,我认为你应该做那个检查。事实上,如果你不测试其中一个*_s()
函数的结果,那么你就会遇到麻烦。