Explorar o código

print_number: Remove trailing zeroes (for doubles)

Max Bruckner %!s(int64=8) %!d(string=hai) anos
pai
achega
1ea72f8260
Modificáronse 4 ficheiros con 47 adicións e 6 borrados
  1. 41 0
      cJSON.c
  2. 3 3
      tests/inputs/test7.expected
  3. 2 2
      tests/print_number.c
  4. 1 1
      tests/print_value.c

+ 41 - 0
cJSON.c

@@ -324,12 +324,44 @@ static void update_offset(printbuffer * const buffer)
     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. */
 static unsigned char *print_number(const cJSON * const item, printbuffer * const output_buffer, const internal_hooks * const hooks)
 {
     unsigned char *output_pointer = NULL;
     double d = item->valuedouble;
     int length = 0;
+    cjbool trim_zeroes = true; /* should at the end be removed? */
 
     if (output_buffer == NULL)
     {
@@ -339,6 +371,8 @@ static unsigned char *print_number(const cJSON * const item, printbuffer * const
     /* value is an int */
     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. */
         output_pointer = ensure(output_buffer, 21, hooks);
         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))
             {
                 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))
             {
                 length = sprintf((char*)output_pointer, "%e", d);
+                trim_zeroes = false; /* don't remove zeroes in engineering notation */
             }
             else
             {
@@ -381,6 +417,11 @@ static unsigned char *print_number(const cJSON * const item, printbuffer * const
 
     output_buffer->offset += (size_t)length;
 
+    if (trim_zeroes)
+    {
+        return trim_trailing_zeroes(output_buffer);
+    }
+
     return output_buffer->buffer + output_buffer->offset;
 }
 

+ 3 - 3
tests/inputs/test7.expected

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

+ 2 - 2
tests/print_number.c

@@ -62,7 +62,7 @@ static void print_number_should_print_positive_integers(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("1000000000000", 10e11);
     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)
 {
-    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("-1000000000000000000000", -10e20);
     assert_print_number("-1.230000e+129", -123e+127);

+ 1 - 1
tests/print_value.c

@@ -66,7 +66,7 @@ static void print_value_should_print_false(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)