diff --git a/src/math/real.cpp b/src/math/real.cpp
index 4bc92db5..392cd256 100644
--- a/src/math/real.cpp
+++ b/src/math/real.cpp
@@ -1468,9 +1468,16 @@ template<> void real::sprintf(char *str, int ndigits) const
 
     /* Normalise x so that mantissa is in [1..9.999] */
     /* FIXME: better use int64_t when the cast is implemented */
+    /* FIXME: does not work with R_MAX and probably R_MIN */
     int exponent = ceil(log10(x));
     x *= pow(R_10(), -(real)exponent);
 
+    if (ndigits < 1)
+        ndigits = 1;
+
+    /* Add a bias to simulate some naive rounding */
+    x += real(4.99f) * pow(R_10(), -(real)(ndigits + 1));
+
     if (x < R_1())
     {
         x *= R_10();
@@ -1488,6 +1495,10 @@ template<> void real::sprintf(char *str, int ndigits) const
         x *= R_10();
     }
 
+    /* Remove excess trailing zeroes */
+    while (str[-1] == '0' && str[-2] != '.')
+        --str;
+
     /* Print exponent information */
     if (exponent)
         str += std::sprintf(str, "e%c%i",