c++ - QJsonDocument::toJson() 不正确的 double

标签 c++ json qt double qjson

在我的项目中,我使用 QJsonDocument::fromJson() 从一个 json 文件中读取。这很好用,但是当我尝试使用 toJson()QJsonDocument 写回文件时,一些 double 已经搞砸了精度。

例如,在具有 QJsonValue 且 double 值为 0.15 的文档上调用 toJson() 将保存为文件 0.14999999999999999。我不想要这个。

这是因为 Qt 源文件 qjsonwriter.cpp 第 126 行 (Qt 5.6.2) 读取:

json += QByteArray::number(d, 'g', std::numeric_limits<double>::digits10 + 2); // ::digits10 is 15

最后的 +2 把我搞得一团糟。如果对 QByteArray::number() 的相同调用的精度为 15(而不是 17),则结果完全符合我的需要...0.15

我理解浮点精度的格式如何导致 double 在它可以表示的范围内受到限制。但是,如果我将精度限制为 15 而不是 17,这会产生匹配输入 double 的效果,这正是我想要的。

我该如何解决这个问题?

显然...我可以编写自己的 Json 解析器,但那是最后的手段。显然我可以编辑 Qt 源代码,但是我的软件已经部署在每个人的安装目录中的 Qt5Core.dll 中,并且我的更新程序并非设计用于更新任何 dll。所以我无法编辑 Qt 源代码。

希望有人能解决这个问题:)

最佳答案

this has the effect of matching the input double precision, which I want.

这个请求没有多大意义。 double 不包含任何关于其精度的信息——它只包含一个值。 0.15、0.1500 和 0.14999999999999999 是完全相同的 double 值,JSON 编写器无法首先知道它是如何从文件中读取的(如果它是从文件中读取的)。

一般来说,您不能像您建议的那样要求最大 15 位精度,因为根据特定值,精确的 double->text->double 往返需要最多 17 位,因此您会编写不正确的四舍五入值.然而,一些 JSON 作者所做的是用读取相同的双反所需的最小小数位数来编写数字。除非您像许多人那样做从 15 到 17 的循环,以如此精确的方式写下数字,然后解析它并查看它是否返回为完全相同的 double 值,否则要正确地进行数字计算远非易事。虽然这会生成“更好”(和更小)的输出,但它需要更多工作并减慢 JSON 写入速度,所以这可能是 Qt 不这样做的原因。

不过,您可以编写自己的 JSON 代码并拥有此功能,对于一个简单的递归实现,我预计大约有 15 行代码。

话虽这么说,但如果您想精确匹配您的输入,这也救不了您——因为这根本不可能。

关于c++ - QJsonDocument::toJson() 不正确的 double ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51257690/

相关文章:

c++ - 如何使用 QT 和 C++ 监听 mysql 数据库中的触发事件?

c++ - PCRE多行匹配问题

c++ - Qt隐藏控制台窗口停止写入日志文件

python - 我需要使用 python json 解析将我的 2 个列表合并为另一个列表

linux - 如何使用 qmake 将库文件构建到 DEB 包中而不是构建到我的系统中?

Ruby、Qt 和第三方小部件

c++ - 带有 visual studio 2013 的 sdl 2(简单示例不起作用,不断崩溃)

c++ - 在从 "operator<<"派生的类中覆盖 "ostream"的问题

javascript - 如何在React Native中显示动态图像?

javascript - 为什么 JSON.stringify 不序列化原型(prototype)值?