json系列(二)cjson,rapidjson,yyjson大整数解析精度对比


前言
上一篇介绍了3种json解析工具的使用方法,对于基础数据的解析没有任何问题。
我们传输的json数据里有unsigned long型数据,需要借助json解析工具得到正确的unsigned long型数据。
本篇对比它们对64bit(8 byte)大整形数据的解析精度。json样本数据random_code为8 byte型大整数。

         

              

  一、cjson解析精度测试

 1 #include "cJSON.h"
 2 
 3 #include 
 4 
 5 // g++ -g -o cjson_precision_test -std=c++11 precision_test.c cJSON.c
 6 
 7 using namespace std;
 8 
 9 int main()
10 {
11     cJSON *json_tmp;
12     cJSON *json_root;
13     
14     char str_buf[1024] = "{\"random_code\":6996903014416199548}";
15 
16     json_root = cJSON_Parse(str_buf);
17 
18     json_tmp = cJSON_GetObjectItem(json_root, "flow_id");
19     if(NULL != json_tmp) {
20         cout << "flow_id:" << json_tmp->valueint << endl;
21         cout << "flow_id:" << json_tmp->valuedouble << endl;
22     }
23 
24     cJSON_Delete(json_root);
25     return 0;
26 }

执行结果:

结果说明:

1、json_tmp->valueint为singed int,可表示的最大整数为:2147483647

2、json_tmp->valuedouble为double类型。double默认为signed类型,最大只能表示63bit

3、通过gdb调试,cjson可表示的最大精度为16位(十进制)

即random_code为:6,903,014,416,199,548,json_tmp->valuedouble可正确表达;

当超过16位,即random_code为:96,903,014,416,199,548,cjson无法解析出正确的大数。

16位(十进制)正确表达

17位(十进制)错误表达,最后两位数据错误

二、rapidjson解析精度测试

 1 #include "rapidjson/document.h"
 2 #include "rapidjson/rapidjson.h"
 3 
 4 #include 
 5 
 6 // g++ -g -o rapidjson_precision_test -std=c++11 precision_test.c
 7 
 8 using namespace std;
 9 
10 int main()
11 {
12     char str_buf[1024] = "{\"random_code\":6996903014416199548}";
13 
14     rapidjson::Document parse_doc;
15     
16     parse_doc.Parse(str_buf);
17 
18     // 确定有random_code场景,直接取值
19     cout << "random_code:" << parse_doc.FindMember("random_code")->value.GetUint64() << endl;
20 
21     return 0;
22 }

执行结果:

三、yyjson解析精度测试

 1 #include "yyjson.h"
 2 
 3 #include 
 4 
 5 // g++ -g -o yyjson_precision_test -std=c++11 precision_test.c yyjson.c
 6 
 7 using namespace std;
 8 
 9 int main()
10 {
11     char str_buf[1024] = "{\"random_code\":6996903014416199548}";
12     
13     yyjson_doc *doc;
14     yyjson_val *root;
15 
16     doc  = yyjson_read(str_buf, strlen(str_buf), 0);
17     root = yyjson_doc_get_root(doc);
18 
19     // 确定有random_code场景,直接取值
20     cout << "random_code:" << yyjson_get_uint(yyjson_obj_get(root, "random_code")) << endl;
21 
22     yyjson_doc_free(doc);
23     return 0;
24 }

执行结果:

结论

cjson无法解析64bit的大整数,rapidjson与yyjson可以正确解析。

如果json数据中存在大数的场景,显然cjson无法满足需求。