逗号分隔的双精度字符串到数组——如何保持精度

问题描述 投票:0回答:1

我正在使用 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);
c json floating-point json-c
1个回答
0
投票

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 版本更新得多。

以下是我的建议:

  • 您可能应该将 json-c 版本升级到更新版本。
  • 您不必担心
    double
    值表示的变化,因为它们应该在目标系统中读取时转换回相同的
    double
    值。
  • 您可能会考虑使用更简单的包来处理 json 格式。
© www.soinside.com 2019 - 2024. All rights reserved.