mirror of
https://github.com/DaveGamble/cJSON.git
synced 2023-08-10 21:13:26 +03:00
Fix an issue where 16-digit integers ending with 0
are printed in exponential format
This commit is contained in:
parent
f0232f21bd
commit
decce2ce6f
24
cJSON.c
24
cJSON.c
@ -541,6 +541,15 @@ static cJSON_bool compare_double(double a, double b)
|
||||
return (fabs(a - b) <= maxVal * DBL_EPSILON);
|
||||
}
|
||||
|
||||
/* check if the double value is in the range [-(2^53-1), 2^53-1] and has no fractional part */
|
||||
#define Number_MAX_SAFE_INTEGER (9007199254740991.0) /* 2^53-1 (double constant) */
|
||||
static cJSON_bool is_safe_integer(double d)
|
||||
{
|
||||
double abs_d = fabs(d);
|
||||
double trunc_d = d >= 0 ? floor(d) : -floor(-d);
|
||||
return (abs_d <= Number_MAX_SAFE_INTEGER && (fabs(d - trunc_d) <= abs_d * DBL_EPSILON));
|
||||
}
|
||||
|
||||
/* Render the number nicely from the given item into a string. */
|
||||
static cJSON_bool print_number(const cJSON * const item, printbuffer * const output_buffer)
|
||||
{
|
||||
@ -562,10 +571,17 @@ static cJSON_bool print_number(const cJSON * const item, printbuffer * const out
|
||||
{
|
||||
length = sprintf((char*)number_buffer, "null");
|
||||
}
|
||||
else if(d == (double)item->valueint)
|
||||
{
|
||||
length = sprintf((char*)number_buffer, "%d", item->valueint);
|
||||
}
|
||||
else if (d == (double)item->valueint)
|
||||
{
|
||||
length = sprintf((char*)number_buffer, "%d", item->valueint);
|
||||
}
|
||||
else if (is_safe_integer(d))
|
||||
{
|
||||
/* Avoid exponential expression in case of integer between
|
||||
* Number.MIN_SAFE_INTEGER and Number.MAX_SAFE_INTEGER
|
||||
*/
|
||||
length = sprintf((char*)number_buffer, "%.0f", d);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Try 15 decimal places of precision to avoid nonsignificant nonzero digits */
|
||||
|
@ -72,6 +72,8 @@ static void print_number_should_print_negative_integers(void)
|
||||
assert_print_number("-1", -1.0);
|
||||
assert_print_number("-32768", -32768.0);
|
||||
assert_print_number("-2147483648", -2147483648.0);
|
||||
assert_print_number("-9007199254740990", -9007199254740990.0);
|
||||
assert_print_number("-9007199254740991", -9007199254740991.0);
|
||||
}
|
||||
|
||||
static void print_number_should_print_positive_integers(void)
|
||||
@ -79,6 +81,8 @@ static void print_number_should_print_positive_integers(void)
|
||||
assert_print_number("1", 1.0);
|
||||
assert_print_number("32767", 32767.0);
|
||||
assert_print_number("2147483647", 2147483647.0);
|
||||
assert_print_number("9007199254740990", 9007199254740990.0);
|
||||
assert_print_number("9007199254740991", 9007199254740991.0);
|
||||
}
|
||||
|
||||
static void print_number_should_print_positive_reals(void)
|
||||
@ -89,6 +93,7 @@ static void print_number_should_print_positive_reals(void)
|
||||
assert_print_number("1.23e+129", 123e+127);
|
||||
assert_print_number("1.23e-126", 123e-128);
|
||||
assert_print_number("3.1415926535897931", 3.1415926535897931);
|
||||
assert_print_number("9.10719925474099e+15", 9107199254740991.5);
|
||||
}
|
||||
|
||||
static void print_number_should_print_negative_reals(void)
|
||||
@ -98,6 +103,7 @@ static void print_number_should_print_negative_reals(void)
|
||||
assert_print_number("-1e+21", -10e20);
|
||||
assert_print_number("-1.23e+129", -123e+127);
|
||||
assert_print_number("-1.23e-126", -123e-128);
|
||||
assert_print_number("-9.10719925474099e+15", -9107199254740991.5);
|
||||
}
|
||||
|
||||
static void print_number_should_print_non_number(void)
|
||||
|
Loading…
Reference in New Issue
Block a user