diff --git a/apps/netutils/json/cJSON_stream_print.c b/apps/netutils/json/cJSON_stream_print.c
index 58f753cf97263d9888ca2704fbf6c34aa49f3d1b..2044a76a9fdbcc948723a50a6cbde66aa19e3e6e 100644
--- a/apps/netutils/json/cJSON_stream_print.c
+++ b/apps/netutils/json/cJSON_stream_print.c
@@ -104,6 +104,13 @@ static inline void stream_puts(cJSON_outstream *stream, char *string)
     }
 }
 
+static bool dbl_equal(double a, double b)
+{
+  double fabs_a = fabs(a);
+  double fabs_b = fabs(b);
+  return fabs(a - b) <= ((fabs_a > fabs_b ? fabs_b : fabs_a) * DBL_EPSILON);
+}
+
 /* Render the number nicely from the given item into a string. */
 
 static void stream_print_number(cJSON *item, cJSON_outstream *stream)
@@ -116,20 +123,58 @@ static void stream_print_number(cJSON *item, cJSON_outstream *stream)
 
   /* Get type and needed length output string. */
 
-  if ((d <= INT_MAX && d >= INT_MIN) &&
-      (fabs(id - d) <= DBL_EPSILON || fabs(floor(d) - d) <= DBL_EPSILON))
+  if (item->valueint == 0 && d == 0.0)
     {
+      /* Handle zero separately as it's relation to DBL_EPSILON is special one
+       * and as zero has two exact presentations in floating point format (positive
+       * zero and negative zero). */
+
+      if (copysign(1.0, d) > 0.0)
+        {
+          /* Simply zero. */
+
+          str[0] = '0';
+          str[1] = '\0';
+          slen = 1;
+          type = 3;
+        }
+      else
+        {
+          /* Negative zero. */
+
+          slen = snprintf(str, sizeof(str), "%s", "-0.0");
+          type = 2;
+        }
+    }
+  else if (item->valueint != 0 && (d <= INT_MAX && d >= INT_MIN) &&
+           dbl_equal(d, id))
+    {
+      /* Integer value can accurately represent this value. */
+
       slen = snprintf(str, sizeof(str), "%d", item->valueint);
       type = 1;
     }
-  else if (fabs(d) < 1.0e-6 || fabs(d) > 1.0e9)
+  else if (fabs(d) < 1.0e-6 || fabs(d) > 1.0e14)
     {
-      slen = snprintf(str, sizeof(str), "%e", d);
+      /* Double can represent 15 significant digits. */
+
+      slen = snprintf(str, sizeof(str), "%.14e", d);
       type = -1;
     }
   else
     {
-      slen = snprintf(str, sizeof(str), "%.10f", d);
+      int ndigits_before_dot = (int)log10(fabs(d));
+      int ndigits_after_dot = 15 - ndigits_before_dot;
+      char fmtstr[8];
+
+      /* Double can represent 15 significant digits. */
+
+      if (ndigits_after_dot < 0)
+        ndigits_after_dot = 0;
+
+      snprintf(fmtstr, sizeof(fmtstr), "%%.%df", ndigits_after_dot);
+
+      slen = snprintf(str, sizeof(str), fmtstr, d);
       type = 0;
     }