QT5中QJsonDocument存储IEEE754双精度数的精度问题求助
解决QT5 QJsonDocument存储双精度数的格式问题
核心问题原因
1.90这类两位小数无法用IEEE754双精度浮点数精确存储,QJsonDocument序列化时会输出该浮点数的真实近似值(如1.8999999999999999),而非你期望的格式化后字符串。以下是无需放弃QT JSON模块或仅操作字符串的可行方案:
解决方案
方法1:修改QT序列化后的JSON字符串
先利用QJsonDocument生成原始JSON字符串,再将目标数值的近似表示替换为指定格式的字符串:
QJsonObject jsonObj; double formattedVal = format(px); jsonObj["amount"] = formattedVal; // 生成原始JSON字符串 QString rawJson = QJsonDocument(jsonObj).toJson(QJsonDocument::Compact); // 替换数值的近似表示为两位小数格式 QString targetFormat = QString::number(formattedVal, 'f', 2); QString rawValStr = QString::number(formattedVal); rawJson.replace(rawValStr, targetFormat); // rawJson即为符合要求的JSON字符串,可直接用于日志或API请求
该方法仅针对目标数值做精准替换,适合结构不复杂的JSON场景,几乎不会出现歧义。
方法2:使用支持精度控制的第三方JSON库
换用轻量头文件库(如nlohmann/json),直接控制数值的输出格式,无需处理QT的默认序列化逻辑:
#include <nlohmann/json.hpp> using json = nlohmann::json; json j; double formattedVal = format(px); // 先将数值格式化为两位小数的字符串再转回double,确保序列化后显示正确 j["amount"] = std::stod(QString::number(formattedVal, 'f', 2).toStdString()); // 生成JSON字符串,默认即可输出正确格式 std::string jsonStr = j.dump();
nlohmann/json是纯头文件库,无需额外编译链接,集成成本极低,且支持灵活的序列化配置。
方法3:手动构造JSON字符串(适合简单结构)
如果JSON结构简单,直接拼接字符串保证数值格式,再解析为QJsonDocument用于后续操作:
QString amountStr = QString::number(format(px), 'f', 2); // 拼接JSON字符串,注意语法正确性 QString jsonStr = QString(R"({"amount": %1})").arg(amountStr); QJsonParseError err; QJsonDocument doc = QJsonDocument::fromJson(jsonStr.toUtf8(), &err); if (!err.error) { // 正常使用doc进行后续QT JSON操作 }
关键提示
只要使用double存储1.90,就无法避免其底层的近似存储,所有方案本质都是通过控制JSON序列化后的字符串格式来满足API要求,而非改变浮点数的存储本身。
内容的提问来源于stack exchange,提问作者OpperDev
相关产品推荐
相关产品推荐

