相关文章推荐
英姿勃勃的松鼠  ·  mysql like 多个 - ...·  5 月前    · 
微笑的大象  ·  iOS ReplayKit ...·  1 年前    · 

我们在Qt中使用Json都是使用QJsonDocument、QJsonArray、QJsonObject、QJsonValue等类。
当我们在QJsonObject中插入浮点数字段时,会发现浮点数的小数位数很长,如下所示:

#include <QJsonDocument>
#include <QJsonArray>
#include <QJsonObject>
#include <QJsonParseError>
#include <QJsonValue>
QJsonObject jo;
float v = 0.12132222111222;
ji.Insert("name", v);
//然后转成Json字符串
QJsonDocument doc(jo);
QString str = doc.toJson(QJsonDocument::Compact);
qDebug() << str.toStdString().c_str();
//以上代码会输出:
//{"name":0.12132222111222}

可见,QJsonObject没有对浮点数做任何的精度控制,其小数点后原来多少位,转为Json后还是多少位。

通常我们不需要在json字符串中记录显示这么长的浮点数。
有一种办法是将浮点数作为字符串插入json,代码如下:

QJsonObject jo;
float v = 0.12132222111222;
QString vs = QString::number(v, 'f', 2);
ji.Insert("name", vs);
//然后转成Json字符串
QJsonDocument doc(jo);
QString str = doc.toJson(QJsonDocument::Compact);
qDebug() << str.toStdString().c_str();
//以上代码会输出:
//{"name":"0.12"}

可见浮点数的精度控制在2位了,但是,浮点数被多出来的一对引号(")包裹了,这实际上是把浮点数类型转为字符串类型处理了,这并不是我们想要的。
如果要直接插入精度可控制的浮点数怎么办呢?方法就是,通过QString将浮点数格式化为目的精度的浮点数字符串,然后将浮点数字符串再转回浮点数,最后插入QJsonObject。代码如下:

QJsonObject jo;
float v = 0.12132222111222;
QString vs = QString::number(v, 'f', 2);
double vd = vs.toDouble();
QJsonValue jv(vd);
ji.Insert("name", jv);
//然后转成Json字符串
QJsonDocument doc(jo);
QString str = doc.toJson(QJsonDocument::Compact);
qDebug() << str.toStdString().c_str();
//以上代码会输出:
//{"name": 0.12}

从输出结果可见,烦人的引号(“)消失了,目的达到了。
需要注意的是,以上代码有一个坑要注意:

//这里一定是double类型和toDouble()函数
double vd = vs.toDouble();
//绝对不能是如下float或者toFLoat()函数
float vd = vs.toDouble();
double vd = vs.toFloat();
float vd = vs.toFloat();

不管是出现以上三种中哪一种错误,都会导致精度控制失效。

这个json数据首先用{}来表示整个数据是一个对象,这个对象里面包括name,age,email,isStudent这些值,还包括了一个hobbies数组,以及一个address对象,这个对象还包括了一些street,city,country的值。它可以表示JSON的基本数据类型,如字符串、数字、布尔值,以及更复杂的数据结构,如对象和数组。值类型:JSON支持多种值类型,包括字符串(String)、数字(Number)、布尔值(Bool)、空值(Null)、对象和数组。toInt(): 将。 在前面的例子当中json序列化可以看到,直接读取浮点数,会导致精度丢失。 目前没有找到很好的解决方案,只是在json中把浮点数改为string,再用相关的函数把string转为double。 这样貌似只能得到6位小数,后面的小数位依然会被丢弃,不过暂已经可以满足我的需求了,等以后需要更加精确的候再去找合适的方法吧。 这里有一篇文章可以借鉴:C++下string类型转double类型 123.json: "ID": 30, "longitude": "112.1234511 小编最近遇到一个问题,之前数据库id不是雪花算法的候,前台json解析是不会丢失精度的,查了一下博客: https://www.cnblogs.com/snandy/p/4943138.html 具体原因 按照小编的理解:在超过15位纯数字的候----------------------------------------------- 此只能模仿十进制进行四舍五入了,但是二进制只有 0 和 1 两个,于是变为 0 舍 1 入。这即是计算机中部分浮点数运算出现误差,丢失精度的根本原因。 问题:JSONObject获取Float类型数据会造成精度获取不准确 解决办法:将Float类型数据数据先转换成String类型,再put进JSONObject里就可以解决这个问题。 public class Test { public static void main(String[] args) { Float num = 1.2589355f; JSONObject jso... QJsonDocument是qt5自带的JSON解析库,通过QJsonDocument可以很方便的创建并解析JSON,但是QJsonDocument有个坑需要注意,QJsonDocument中JSON类型是QJsonObject,QJsonObject支持的参数是QJsonValue,但是阅读QJsonValue文档会发现,它所支持的种类型里是没有longlong的,对与长整型的处理,它使用的是double。double在处理长整数的候会有长度限制,超过长度后就会丢失精度。 https://www.cnblogs.com/ybqjymy/p/17264853.html https://www.jb51.net/article/260149.htm https://blog.csdn.net/cpp_learner/article/details/118421096 之前介绍了许多 C++ 的 Json 第三方库, 下面介绍一下 JsonQt... JSON(JavaScript Object Notation,js对象标记)是一种轻量级的数据交换格式。它基于ECMAScript的一个子集,使用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的的层次结构使得JSON成为理想的数据交换语言。易于人阅读和编写,同也易于机器解析和生成,并有效的提升网络传输效率。关于JSON的更多解释,请参看JSON官网。 QT解析 JSON 格式的数据 JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。JSON 采用完全独立于语言的文本格式,这些特性使 JSON 成为理想的数据交换语言。易于人阅读和编写,同也易于机器解析和生成。 1、基础结构 名称/值对 集合(A collection of name/value pairs)。不同的语言中,它被理解为对象(object)、记录(record)、结构(struct)、字典(dictionary)、哈希表(hash tabl **使用`json.Number`类型**:在解析JSON,可以使用`json.Number`类型来保留原始的数值表示,然后再根据需要转换为`int64`。1. **大整数**:如果JSON中的数字超出了`int64`的范围(-2^63 到 2^63-1),那么在转换可能会丢失精度。- **手动处理**:在解析JSON之前,你可以手动检查数字的大小,如果超出了`int64`的范围,可以提前进行处理。3. **负数**:对于负数,如果它超出了`int64`的表示范围,转换同样会丢失精度。 近期在工作中遇到个问题通过post请求从其他系统(好像是C#写的)获得json字符串{"geometry":{"rings":[[[40426489.331430912,3001752.0858958033],[40426225.692211367,3001750.0779145896],[40426202.957955509,3001594.0301330695],[40426290.95912... 这是因为 21/100 没有精确的浮点表示,默认情况下,我们使用17位数字,因为这是将double的任何值明确表示为字符串所需的数字。这与15==DBL_DIG==std::numeric_limits<double>::digitals10不同,后者是可以在不失真的情况下从字符串解析到double并返回的最大位数。我们选择了足够多的数字来完美地表示每一个可能的双精度值。所以只需要15位数字的精度,因为15位数字可以在不失真的情况下解析和重新打印,但这会牺牲对double数据类型的完整尾数的访问。