什么浮点值使 sprintf_s() 产生“1.#QO”?

发布于 2024-11-06 07:34:37 字数 793 浏览 5 评论 0原文

我有一些(传统嵌入式 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 所以它看起来像这可能是 NaN 的 Microsoft 特定表示形式?

I have some (legacy embedded c) code which produces a .csv file by means of some sprintf calls. Occasionally I see values of 1.#QO. I've tried reproducing those values with conditions which should give negative infinity, positive infinity and NaN but none of them appear to give me the magical 1.#QO result. So what is it that produces that value?

...and yes, I know there's obviously something going wrong in the maths which produce that value, but understanding what it means would assist in the debugging effort.

[Edit 1] The actual line which does the conversion is:

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

where:

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

I'm compiling with MS Visual Studio 2008.

[Edit 2] A bit more digging shows 0xFFFFFFFF gives -1.#QO:

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

..and looking at that in the Visual Studio debugger expands it to -1.#QNAN00 so it looks like this is probably a Microsoft-specific representation of NaN?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

孤独岁月 2024-11-13 07:34:37

“-1.#QO”在“四舍五入”小数点后 3 位后为“-1.#QNAN”。当 'A' >= '5' 且 'N' + 1 == 'O' 时,N 舍入为 O。

这也是调试器显示“-1.#QNAN00”的类似原因,因为它打印了 7 个位置,并在末尾添加了填充零。

QNaN 是安静的 NaN

"-1.#QO" is "-1.#QNAN" after "rounding" for 3 places after the decimal. The N rounds to an O as 'A' >= '5' and 'N' + 1 == 'O'.

This is similarly why your debugger shows "-1.#QNAN00", as it prints with 7 places and adds padding zeros to the end.

QNaN is quiet NaN.

冷清清 2024-11-13 07:34:37

经过大量摆弄后,我可以得出结论,将 4 字节浮点数设置为 0x7FFFFFFF 并将其传递到 sprintf_s ,格式说明符为 %.3f< /code> 给了我 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

After a lot of fiddling around I can conclusively say that setting a 4-byte float to 0x7FFFFFFF and passing it into sprintf_s with a format specifier of %.3f is what gave me 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

...it seems that the %.3f format specifier was cropping the NAN result so what should have been 1.#QNAN0 was being chopped down to 1.#QO.

凑诗 2024-11-13 07:34:37

稍微谷歌一下就发现有除以 0 的错误。但如果是这样的话,我会期待一些不同的事情。也就是说,它似乎特定于 MS/Visual C。

A little googling points to a divide by 0 error. Though I would expect something different if that were the case. That said, it appears to be specific to MS/Visual C.

贵在坚持 2024-11-13 07:34:37

您检查过 sprintf_s() 是否返回失败吗?如果是这样,则不应使用该结果。由于代码看起来不像您检查过的那样,我认为您应该进行检查。事实上,如果您不测试 *_s() 函数之一的结果,您就会遇到麻烦。

Did you check whether sprintf_s() returned a failure? If it does, you should not use the result. Since the code doesn't look like you checked, I think you should do that checking. In fact, if you don't test the result from one of the *_s() functions, you are headed for trouble.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文