You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.01 12:22:29