diff --git a/src/modp_numtoa.c b/src/modp_numtoa.c index 6475ad5fe6..e7b074d876 100644 --- a/src/modp_numtoa.c +++ b/src/modp_numtoa.c @@ -6,6 +6,7 @@ #include #include #include +#include // other interesting references on num to string convesion // http://www.jb.man.ac.uk/~slowe/cpp/itoa.html @@ -88,8 +89,28 @@ void modp_dtoa(double value, char* str, int prec) str[0] = 'n'; str[1] = 'a'; str[2] = 'n'; str[3] = '\0'; return; } + + /* we'll work in positive values and deal with the + negative sign issue later */ + int neg = 0; + if (value < 0) { + neg = 1; + value = -value; + } + /* if input is larger than thres_max, revert to exponential */ - const double thres_max = (double)(0x7FFFFFFF); + const double thres_max = (double)(INT_MAX); + + /* for very large numbers switch back to native sprintf for exponentials. + anyone want to write code to replace this? */ + /* + normal printf behavior is to print EVERY whole number digit + which can be 100s of characters overflowing your buffers == bad + */ + if (value >= thres_max) { + sprintf(str, "%e", neg ? -value : value); + return; + } double diff = 0.0; char* wstr = str; @@ -101,16 +122,6 @@ void modp_dtoa(double value, char* str, int prec) prec = 9; } - - /* we'll work in positive values and deal with the - negative sign issue later */ - int neg = 0; - if (value < 0) { - neg = 1; - value = -value; - } - - int whole = (int) value; double tmp = (value - whole) * _pow10[prec]; uint32_t frac = (uint32_t)(tmp); @@ -129,17 +140,6 @@ void modp_dtoa(double value, char* str, int prec) ++frac; } - /* for very large numbers switch back to native sprintf for exponentials. - anyone want to write code to replace this? */ - /* - normal printf behavior is to print EVERY whole number digit - which can be 100s of characters overflowing your buffers == bad - */ - if (value > thres_max) { - sprintf(str, "%e", neg ? -value : value); - return; - } - if (prec == 0) { diff = value - whole; if (diff > 0.5) { @@ -189,8 +189,27 @@ void modp_dtoa2(double value, char* str, int prec) return; } + /* we'll work in positive values and deal with the + negative sign issue later */ + int neg = 0; + if (value < 0) { + neg = 1; + value = -value; + } + /* if input is larger than thres_max, revert to exponential */ - const double thres_max = (double)(0x7FFFFFFF); + const double thres_max = (double)(INT_MAX); + + /* for very large numbers switch back to native sprintf for exponentials. + anyone want to write code to replace this? */ + /* + normal printf behavior is to print EVERY whole number digit + which can be 100s of characters overflowing your buffers == bad + */ + if (value >= thres_max) { + sprintf(str, "%e", neg ? -value : value); + return; + } int count; double diff = 0.0; @@ -203,16 +222,6 @@ void modp_dtoa2(double value, char* str, int prec) prec = 9; } - - /* we'll work in positive values and deal with the - negative sign issue later */ - int neg = 0; - if (value < 0) { - neg = 1; - value = -value; - } - - int whole = (int) value; double tmp = (value - whole) * _pow10[prec]; uint32_t frac = (uint32_t)(tmp); @@ -231,17 +240,6 @@ void modp_dtoa2(double value, char* str, int prec) ++frac; } - /* for very large numbers switch back to native sprintf for exponentials. - anyone want to write code to replace this? */ - /* - normal printf behavior is to print EVERY whole number digit - which can be 100s of characters overflowing your buffers == bad - */ - if (value > thres_max) { - sprintf(str, "%e", neg ? -value : value); - return; - } - if (prec == 0) { diff = value - whole; if (diff > 0.5) { @@ -301,21 +299,6 @@ void modp_dtoa3(double value, char* str, int n, int prec) return; } - /* if input is larger than thres_max, revert to exponential */ - const double thres_max = (double)(0x7FFFFFFF); - - int count; - double diff = 0.0; - char* wstr = str; - - if (prec < 0) { - prec = 0; - } else if (prec > 9) { - /* precision of >= 10 can lead to overflow errors */ - prec = 9; - } - - /* we'll work in positive values and deal with the negative sign issue later */ int neg = 0; @@ -324,32 +307,23 @@ void modp_dtoa3(double value, char* str, int n, int prec) value = -value; } - - int whole = (int) value; - double tmp = (value - whole) * _pow10[prec]; - uint32_t frac = (uint32_t)(tmp); - diff = tmp - frac; - - if (diff > 0.5) { - ++frac; - /* handle rollover, e.g. case 0.99 with prec 1 is 1.0 */ - if (frac >= _pow10[prec]) { - frac = 0; - ++whole; - } - } else if (diff == 0.5 && ((frac == 0) || (frac & 1))) { - /* if halfway, round up if odd, OR - if last digit is 0. That last part is strange */ - ++frac; + if (prec < 0) { + prec = 0; + } else if (prec > 9) { + /* precision of >= 10 can lead to overflow errors */ + prec = 9; } + /* if input is larger than thres_max, revert to exponential */ + const double thres_max = (double)(INT_MAX); + /* for very large numbers switch back to native sprintf for exponentials. anyone want to write code to replace this? */ /* normal printf behavior is to print EVERY whole number digit which can be 100s of characters overflowing your buffers == bad */ - if (value > thres_max) { + if (value >= thres_max) { /* ---- Modified part, compared to modp_dtoa3. */ int i = snprintf(str, n, "%.*f", prec, neg ? -value : value); @@ -373,6 +347,28 @@ void modp_dtoa3(double value, char* str, int n, int prec) /* ---- End of modified part.. */ } + int count; + double diff = 0.0; + char* wstr = str; + + int whole = (int) value; + double tmp = (value - whole) * _pow10[prec]; + uint32_t frac = (uint32_t)(tmp); + diff = tmp - frac; + + if (diff > 0.5) { + ++frac; + /* handle rollover, e.g. case 0.99 with prec 1 is 1.0 */ + if (frac >= _pow10[prec]) { + frac = 0; + ++whole; + } + } else if (diff == 0.5 && ((frac == 0) || (frac & 1))) { + /* if halfway, round up if odd, OR + if last digit is 0. That last part is strange */ + ++frac; + } + if (prec == 0) { diff = value - whole; if (diff > 0.5) {