feat(cjson): Add function to encode json number when "sprintf" not support float

Newlib use nano mode as default. When enable nano mode, cjson use internal function to encode for float data.
Otherwise using "sprintf" to encode float data.
This commit is contained in:
Dong Heng
2018-10-11 20:17:52 +08:00
parent c4f2a58351
commit e5df03c277
3 changed files with 51 additions and 2 deletions

View File

@ -56,6 +56,10 @@
#pragma GCC visibility pop
#endif
#ifndef CJSON_SPRINTF_FLOAT
#define CJSON_SPRINTF_FLOAT 0
#endif
#include "cJSON.h"
/* define our own boolean type */
@ -480,7 +484,6 @@ static cJSON_bool print_number(const cJSON * const item, printbuffer * const out
size_t i = 0;
unsigned char number_buffer[26]; /* temporary buffer to print the number into */
unsigned char decimal_point = get_decimal_point();
double test;
if (output_buffer == NULL)
{
@ -494,6 +497,9 @@ static cJSON_bool print_number(const cJSON * const item, printbuffer * const out
}
else
{
#if CJSON_SPRINTF_FLOAT
double test;
/* Try 15 decimal places of precision to avoid nonsignificant nonzero digits */
length = sprintf((char*)number_buffer, "%1.15g", d);
@ -503,6 +509,45 @@ static cJSON_bool print_number(const cJSON * const item, printbuffer * const out
/* If not, print with 17 decimal places of precision */
length = sprintf((char*)number_buffer, "%1.17g", d);
}
#else
long d32 = (long)d;
length = sprintf((char*)number_buffer, "%ld", d32);
if ((double)d32 != d) {
size_t precision = 14;
unsigned char *pbuf = number_buffer;
if (d < 0.0) {
d = (double)d32 - d + 0.00000000000001;
} else {
d = d - (double)d32;
}
pbuf = &number_buffer[length];
*pbuf++ = '.';
length++;
while (d > 0.0 && precision--) {
d *= 10.0;
unsigned char tmp = (unsigned char)d;
*pbuf++ = tmp + '0';
length++;
d -= (double)tmp;
}
pbuf = &number_buffer[length - 1];
while (*pbuf == '0') {
pbuf--;
length--;
}
*++pbuf = 0;
}
#endif
}
/* sprintf failed or buffer overrun occured */