QJsonDocument :: toJson()不正确的双精度

时间:2018-07-10 05:17:46

标签: c++ json qt double qjson

在我的项目中,我使用QJsonDocument::fromJson()从json文件中读取内容。效果很好,但是当我尝试将QJsonDocument写回toJson()到文件中时,某些双精度值已经搞砸了。

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

这是因为Qt源文件qjsonwriter.cpp at line 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

我了解浮点精度的格式如何导致双精度表示形式受到限制。但是,如果我将精度限制为15而不是17,则具有匹配我想要的输入双精度的效果。

我该如何解决?

显然...我可以编写自己的Json解析器,但这是不得已的方法。显然,我可以编辑Qt源代码,但是我的软件已经部署了,每个人的安装目录中都包含了Qt5Core.dll,而且我的更新程序也不旨在更新任何dll。所以我不能编辑Qt源代码。

手指越过某人对此有神奇的解决方法:)

1 个答案:

答案 0 :(得分:1)

  

这具有匹配我想要的输入双精度的效果。

此请求没有多大意义。双精度型不包含有关精度的任何信息-它仅带有值。 0.15、0.1500和0.14999999999999999是完全相同的双精度值,并且JSON编写器无法知道首先是如何从文件中读取它的( if 完全是从文件中读取的)。

通常,您不能像建议的那样要求最多15位精度,因为根据特定值,精确的double-> text-> double往返最多需要17位,因此您将编写不正确的舍入值。但是,某些JSON编写者所做的就是用读取相同的double back 所需的最小小数位数写数字。除非您-像许多人一样-进行从15到17的循环,否则很难正确地进行数字运算,以这种精度编写数字,将其解析回去,然后看是否返回为完全相同的double值。尽管这会生成“更细”(更小)的输出,但它的工作量更大,并且会降低JSON的写入速度,因此这就是Qt可能不这样做的原因。

仍然,您可以编写自己的JSON编写代码并具有此功能,对于简单的递归实现,我希望有15行代码。

话又说回来,如果您想精确地匹配您的输入,那将不会节省您-因为这是根本不可能的。