print_number: Remove trailing zeroes (for doubles)

This commit is contained in:
Max Bruckner 2017-03-01 13:20:14 +01:00
parent e78bc42362
commit 1ea72f8260
4 changed files with 47 additions and 6 deletions

41
cJSON.c
View File

@ -324,12 +324,44 @@ static void update_offset(printbuffer * const buffer)
buffer->offset += strlen((const char*)buffer_pointer); buffer->offset += strlen((const char*)buffer_pointer);
} }
/* Removes trailing zeroes from the end of a printed number */
static unsigned char *trim_trailing_zeroes(printbuffer * const buffer)
{
size_t offset = 0;
unsigned char *content = NULL;
if ((buffer == NULL) || (buffer->buffer == NULL) || (buffer->offset < 1))
{
return NULL;
}
offset = buffer->offset - 1;
content = buffer->buffer;
while ((offset > 0) && (content[offset] == '0'))
{
offset--;
}
if ((offset > 0) && (content[offset] == '.'))
{
offset--;
}
offset++;
content[offset] = '\0';
buffer->offset = offset;
return content + offset;
}
/* Render the number nicely from the given item into a string. */ /* Render the number nicely from the given item into a string. */
static unsigned char *print_number(const cJSON * const item, printbuffer * const output_buffer, const internal_hooks * const hooks) static unsigned char *print_number(const cJSON * const item, printbuffer * const output_buffer, const internal_hooks * const hooks)
{ {
unsigned char *output_pointer = NULL; unsigned char *output_pointer = NULL;
double d = item->valuedouble; double d = item->valuedouble;
int length = 0; int length = 0;
cjbool trim_zeroes = true; /* should at the end be removed? */
if (output_buffer == NULL) if (output_buffer == NULL)
{ {
@ -339,6 +371,8 @@ static unsigned char *print_number(const cJSON * const item, printbuffer * const
/* value is an int */ /* value is an int */
if ((fabs(((double)item->valueint) - d) <= DBL_EPSILON) && (d <= INT_MAX) && (d >= INT_MIN)) if ((fabs(((double)item->valueint) - d) <= DBL_EPSILON) && (d <= INT_MAX) && (d >= INT_MIN))
{ {
trim_zeroes = false; /* don't remove zeroes for integers */
/* 2^64+1 can be represented in 21 chars. */ /* 2^64+1 can be represented in 21 chars. */
output_pointer = ensure(output_buffer, 21, hooks); output_pointer = ensure(output_buffer, 21, hooks);
if (output_pointer != NULL) if (output_pointer != NULL)
@ -361,10 +395,12 @@ static unsigned char *print_number(const cJSON * const item, printbuffer * const
else if ((fabs(floor(d) - d) <= DBL_EPSILON) && (fabs(d) < 1.0e60)) else if ((fabs(floor(d) - d) <= DBL_EPSILON) && (fabs(d) < 1.0e60))
{ {
length = sprintf((char*)output_pointer, "%.0f", d); length = sprintf((char*)output_pointer, "%.0f", d);
trim_zeroes = false; /* don't remove zeroes for "big integers" */
} }
else if ((fabs(d) < 1.0e-6) || (fabs(d) > 1.0e9)) else if ((fabs(d) < 1.0e-6) || (fabs(d) > 1.0e9))
{ {
length = sprintf((char*)output_pointer, "%e", d); length = sprintf((char*)output_pointer, "%e", d);
trim_zeroes = false; /* don't remove zeroes in engineering notation */
} }
else else
{ {
@ -381,6 +417,11 @@ static unsigned char *print_number(const cJSON * const item, printbuffer * const
output_buffer->offset += (size_t)length; output_buffer->offset += (size_t)length;
if (trim_zeroes)
{
return trim_trailing_zeroes(output_buffer);
}
return output_buffer->buffer + output_buffer->offset; return output_buffer->buffer + output_buffer->offset;
} }

View File

@ -1,7 +1,7 @@
[{ [{
"precision": "zip", "precision": "zip",
"Latitude": 37.766800, "Latitude": 37.7668,
"Longitude": -122.395900, "Longitude": -122.3959,
"Address": "", "Address": "",
"City": "SAN FRANCISCO", "City": "SAN FRANCISCO",
"State": "CA", "State": "CA",
@ -10,7 +10,7 @@
}, { }, {
"precision": "zip", "precision": "zip",
"Latitude": 37.371991, "Latitude": 37.371991,
"Longitude": -122.026020, "Longitude": -122.02602,
"Address": "", "Address": "",
"City": "SUNNYVALE", "City": "SUNNYVALE",
"State": "CA", "State": "CA",

View File

@ -62,7 +62,7 @@ static void print_number_should_print_positive_integers(void)
static void print_number_should_print_positive_reals(void) static void print_number_should_print_positive_reals(void)
{ {
assert_print_number("0.123000", 0.123); assert_print_number("0.123", 0.123);
assert_print_number("1.000000e-09", 10e-10); assert_print_number("1.000000e-09", 10e-10);
assert_print_number("1000000000000", 10e11); assert_print_number("1000000000000", 10e11);
assert_print_number("1.230000e+129", 123e+127); assert_print_number("1.230000e+129", 123e+127);
@ -71,7 +71,7 @@ static void print_number_should_print_positive_reals(void)
static void print_number_should_print_negative_reals(void) static void print_number_should_print_negative_reals(void)
{ {
assert_print_number("-0.012300", -0.0123); assert_print_number("-0.0123", -0.0123);
assert_print_number("-1.000000e-09", -10e-10); assert_print_number("-1.000000e-09", -10e-10);
assert_print_number("-1000000000000000000000", -10e20); assert_print_number("-1000000000000000000000", -10e20);
assert_print_number("-1.230000e+129", -123e+127); assert_print_number("-1.230000e+129", -123e+127);

View File

@ -66,7 +66,7 @@ static void print_value_should_print_false(void)
static void print_value_should_print_number(void) static void print_value_should_print_number(void)
{ {
assert_print_value("1.500000"); assert_print_value("1.5");
} }
static void print_value_should_print_string(void) static void print_value_should_print_string(void)