天天看點

cJSON精度丢失問題

問題複現步驟:

1) 輸入字元串:

{

    "V":0.12345678

}

2) 字元串轉成cJSON對象

3) 調用cJSON_Print将cJSON對象再轉成字元串

4) 再将字元串轉成cJSON對象

5) 保留8位精度方式調用printf列印值,輸出變成:0.123456

問題的原因出在cJSON的print_number函數:

static char *print_number(cJSON *item)

    char *str;

    double d = item->valuedouble;

    if (fabs(((double) item->valueint) - d)

                    && d >= INT_MIN)

    {

        str = (char*) cJSON_malloc(21); /* 2^64+1 can be represented in 21 chars. */

        if (str)

            sprintf(str, "%d", item->valueint);

    }

    else

        str = (char*) cJSON_malloc(64); /* This is a nice tradeoff. */

        {

            if (fabs(floor(d) - d)

                sprintf(str, "%.0f", d);

            else if (fabs(d) 1.0e9)

                sprintf(str, "%e", d);

            else

                sprintf(str, "%f", d);

        }

    return str;

最後一個sprintf調用沒有指定保留的精度,預設為6位,這就是問題的原因。

注:float的精度為6~7位有效數字,double的精度為15~16位。