油嘴滑舌:g_ascii_dtostr 不精确?

发布于 2024-12-23 17:08:26 字数 581 浏览 6 评论 0原文

我对一些 glib 函数(例如“g_ascii_dtostr”)(以及使用双精度的 GKeyFile 函数)的工作方式有点感兴趣。

考虑这一行:

gchar buf[30];
g_message("Double: %f, as String: %s", 0.2, g_ascii_dtostr(buf, 30, 0.2));

哪个输出

Double: 0.200000, as String: 0.20000000000000001

(只有当我将缓冲区大小设置得足够高时才会发生奇怪的转换)

当我(例如)将双“1.9”存储在 GKeyFile 中时会发生类似的事情,但在生成的文件中它被保存为“1.8999999999999999”。 显然,通过“g_ascii_strtod”返回的转换应该是无损的,但它仍然困扰着我为什么会首先发生这种奇怪的情况。这也使我的配置键值文件变得非常难看。

我想我已经在某处读到过使用中间“long double”类型,但这仍然无法澄清为什么转换后的值是“脏”的,因为例如我认为从 int 到 double 的转换没有任何类似的效果。

I am a little bit intrigued by the way some glib functions such as "g_ascii_dtostr" (and the GKeyFile functions using doubles) work.

Consider this line:

gchar buf[30];
g_message("Double: %f, as String: %s", 0.2, g_ascii_dtostr(buf, 30, 0.2));

Which outputs

Double: 0.200000, as String: 0.20000000000000001

(The weird conversion only happens when I set the buffer size high enough though)

Similar things happen when I (for example) store the double "1.9" in a GKeyFile, but in the resulting file it is saved as "1.8999999999999999".
Apparently the conversion back through "g_ascii_strtod" is supposed to be lossless, but it still bothers me why this weirdness happens in the first place. Also this makes my config key-value files pretty ugly..

I think I have read somewhere once that an intermediate "long double" type is used, but this still wouldn't clarify why the converted value is "dirty", because e.g. a conversion from int to double for doesn't have any similar effects I think.

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

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

发布评论

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

评论(1

当爱已成负担 2024-12-30 17:08:26

来自文档

“该函数生成足够的精度,使用 g_ascii_strtod() 将字符串转换回相同的机器编号(在具有 IEEE 兼容 64 位双精度数的机器上)。”

正如 caf 在他的评论中指出的那样, %f 说明符在六位十进制数字后截断,因此 g_ascii_strtod() 为您提供更准确的值。如果您想要此截断,可以使用 g_ascii_formatd()。

From the documentation:

"This functions generates enough precision that converting the string back using g_ascii_strtod() gives the same machine-number (on machines with IEEE compatible 64bit doubles)."

As caf noted in his comment, the %f specifier truncates after six decimal digits, so g_ascii_strtod() gives you the more accurate value. You can use g_ascii_formatd() if you want this truncation.

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