我正在使用 JSON-C 库 v0.11 来输出 JSON。我在 char * 中有一个双精度字符串,我需要将其输出为数组。
我有:
const char* doubles = "0.1234, 0.5678, 1.1234, 1.5678";
我想输出:
"doubles", [0.1234, 0.5678, 1.1234, 1.5678]
我的问题是,使用
json_object_new_double
时,JSON-C 库会添加尾随零,我希望我的双精度数是准确的。
有解决方法吗?
char *token = strtok(doubles, ",");
while (token != NULL) {
double current = atof(token);
json_object_array_add(my_array, json_object_new_double(current));
token = strtok(NULL, ",");
}
// Add the key-value pair as an array
json_object_object_add(root_obj, "my_array", my_array);
json-c 库使用
snprintf
和格式 "%.17g"
将 double
值转换为字符串进行输出。这会产生准确的转换,使得任何 2 个不同的 double
值都会产生不同的输出,并将该输出转换回原始 double
值。
在大多数系统中使用的 IEEE 格式中,没有将 0.5678
作为
double
的精确二进制表示。普遍存在的
IEEE 二进制 64 位格式中最接近的
double
值是 5114287736841935 * 2-53,其精确的十进制表示为 0.56779999999999997140065488565596751868724822998046875
(以及十六进制浮点格式中的 0x1.22b6ae7d566cfp-1
)。如果您将值转换为 4 到 16 位小数,则转换会生成 0.5678
,但库使用 17 位小数来确保所有 double
值产生不同的输出,因此在您的系统上,库生成的字符串是 0.56779999999999997
,但 atof("0.56779999999999997")
和 atof("0.5678")
应产生相同的 double
值。
请注意,C 标准不要求此行为,因此在不同的系统上输出可能是
0.5678
。
为了避免这个问题,你需要使用小数浮点数,json-c似乎不支持这种方式,或者指定json-c操作的字符串转换中的最大小数位数的方法,但包没有提供这是一种简单的方法,即使在当前版本 0.17 中,也比旧的 0.11 版本更新得多。
以下是我的建议:
double
值表示的变化,因为它们应该在目标系统中读取时转换回相同的 double
值。