From df76c3416dfb7013b0c228fe220910dc6848c080 Mon Sep 17 00:00:00 2001 From: Nick Galbreath Date: Thu, 22 Sep 2016 23:29:31 +0000 Subject: [PATCH] Issue #38 #39 #40 rouding issue --- ChangeLog | 3 + src/modp_numtoa.c | 548 +++++++++++++------------ test/modp_numtoa_test.c | 863 ++++++++++++++++++++-------------------- 3 files changed, 706 insertions(+), 708 deletions(-) diff --git a/ChangeLog b/ChangeLog index 35e97e1..7d8038b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,9 @@ ChangeLog Yeah, I know this isn't quite the right format. +22-Sep-2016 + * Fix nasty rounding bug in dtoa functions + 01-Nov-2013: * Added new XML, HTML and UTF-8 functions * Fixed warnings for latest compilers diff --git a/src/modp_numtoa.c b/src/modp_numtoa.c index 5abe459..c419045 100644 --- a/src/modp_numtoa.c +++ b/src/modp_numtoa.c @@ -16,6 +16,8 @@ * Version 19-Nov-2007 * Fixed round-to-even rules to match printf * thanks to Johannes Otepka + * Version 22-Sep-2016 + * Fixed rounding error with decimals ending in 5 and low precision */ /** @@ -23,165 +25,168 @@ * 10^0 to 10^9 */ static const double powers_of_10[] = {1, 10, 100, 1000, 10000, 100000, 1000000, - 10000000, 100000000, 1000000000}; + 10000000, 100000000, 1000000000}; static void strreverse(char* begin, char* end) { - char aux; - while (end > begin) - aux = *end, *end-- = *begin, *begin++ = aux; + char aux; + while (end > begin) + aux = *end, *end-- = *begin, *begin++ = aux; } size_t modp_itoa10(int32_t value, char* str) { - char* wstr=str; - /* Take care of sign */ - uint32_t uvalue = (value < 0) ? (uint32_t)(-value) : (uint32_t)(value); - /* Conversion. Number is reversed. */ - do *wstr++ = (char)(48 + (uvalue % 10)); while(uvalue /= 10); - if (value < 0) *wstr++ = '-'; - *wstr='\0'; - - /* Reverse string */ - strreverse(str,wstr-1); - return (size_t)(wstr - str); + char* wstr=str; + /* Take care of sign */ + uint32_t uvalue = (value < 0) ? (uint32_t)(-value) : (uint32_t)(value); + /* Conversion. Number is reversed. */ + do *wstr++ = (char)(48 + (uvalue % 10)); while(uvalue /= 10); + if (value < 0) *wstr++ = '-'; + *wstr='\0'; + + /* Reverse string */ + strreverse(str,wstr-1); + return (size_t)(wstr - str); } size_t modp_uitoa10(uint32_t value, char* str) { - char* wstr=str; - /* Conversion. Number is reversed. */ - do *wstr++ = (char)(48 + (value % 10)); while (value /= 10); - *wstr='\0'; - /* Reverse string */ - strreverse(str, wstr-1); - return (size_t)(wstr - str); + char* wstr=str; + /* Conversion. Number is reversed. */ + do *wstr++ = (char)(48 + (value % 10)); while (value /= 10); + *wstr='\0'; + /* Reverse string */ + strreverse(str, wstr-1); + return (size_t)(wstr - str); } size_t modp_litoa10(int64_t value, char* str) { - char* wstr=str; - uint64_t uvalue = (value < 0) ? (uint64_t)(-value) : (uint64_t)(value); + char* wstr=str; + uint64_t uvalue = (value < 0) ? (uint64_t)(-value) : (uint64_t)(value); - /* Conversion. Number is reversed. */ - do *wstr++ = (char)(48 + (uvalue % 10)); while(uvalue /= 10); - if (value < 0) *wstr++ = '-'; - *wstr='\0'; + /* Conversion. Number is reversed. */ + do *wstr++ = (char)(48 + (uvalue % 10)); while(uvalue /= 10); + if (value < 0) *wstr++ = '-'; + *wstr='\0'; - /* Reverse string */ - strreverse(str,wstr-1); - return (size_t)(wstr - str); + /* Reverse string */ + strreverse(str,wstr-1); + return (size_t)(wstr - str); } size_t modp_ulitoa10(uint64_t value, char* str) { - char* wstr=str; - /* Conversion. Number is reversed. */ - do *wstr++ = (char)(48 + (value % 10)); while (value /= 10); - *wstr='\0'; - /* Reverse string */ - strreverse(str, wstr-1); - return (size_t)(wstr - str); + char* wstr=str; + /* Conversion. Number is reversed. */ + do *wstr++ = (char)(48 + (value % 10)); while (value /= 10); + *wstr='\0'; + /* Reverse string */ + strreverse(str, wstr-1); + return (size_t)(wstr - str); } size_t modp_dtoa(double value, char* str, int prec) { - /* Hacky test for NaN - * under -fast-math this won't work, but then you also won't - * have correct nan values anyways. The alternative is - * to link with libmath (bad) or hack IEEE double bits (bad) - */ - if (! (value == value)) { - str[0] = 'n'; str[1] = 'a'; str[2] = 'n'; str[3] = '\0'; - return (size_t)3; - } - /* if input is larger than thres_max, revert to exponential */ - const double thres_max = (double)(0x7FFFFFFF); - - 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; - if (value < 0) { - neg = 1; - value = -value; - } - - - int whole = (int) value; - double tmp = (value - whole) * powers_of_10[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 >= powers_of_10[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; - } - - /* 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 strlen(str); - } - - if (prec == 0) { - diff = value - whole; - if (diff > 0.5) { - /* greater than 0.5, round up, e.g. 1.6 -> 2 */ - ++whole; - } else if (diff == 0.5 && (whole & 1)) { - /* exactly 0.5 and ODD, then round up */ - /* 1.5 -> 2, but 2.5 -> 2 */ - ++whole; - } - } else { - int count = prec; - /* now do fractional part, as an unsigned number */ - do { - --count; - *wstr++ = (char)(48 + (frac % 10)); - } while (frac /= 10); - /* add extra 0s */ - while (count-- > 0) *wstr++ = '0'; - /* add decimal */ - *wstr++ = '.'; - } - - /* do whole part - * Take care of sign - * Conversion. Number is reversed. - */ - do *wstr++ = (char)(48 + (whole % 10)); while (whole /= 10); - if (neg) { - *wstr++ = '-'; - } - *wstr='\0'; - strreverse(str, wstr-1); - return (size_t)(wstr - str); + /* Hacky test for NaN + * under -fast-math this won't work, but then you also won't + * have correct nan values anyways. The alternative is + * to link with libmath (bad) or hack IEEE double bits (bad) + */ + if (! (value == value)) { + str[0] = 'n'; str[1] = 'a'; str[2] = 'n'; str[3] = '\0'; + return (size_t)3; + } + /* if input is larger than thres_max, revert to exponential */ + const double thres_max = (double)(0x7FFFFFFF); + + 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; + if (value < 0) { + neg = 1; + value = -value; + } + + // given 0.05, prec=1 + // whole = 0 + // tmp = (0.05)* 10 = 0.5 + // frac = 0 + // diff = tmp -frac == 0.5 - 0.0 = 0.5 + // + int whole = (int) value; + double tmp = (value - whole) * powers_of_10[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 >= powers_of_10[prec]) { + frac = 0; + ++whole; + } + } else if (diff == 0.5 && ((frac & 1))) { + /* if halfway, round up if odd, OR + if last digit is 0. That last part is strange */ + ++frac; + if (frac >= powers_of_10[prec]) { + frac = 0; + ++whole; + } + } else if (diff == 0.5 && (prec > 0 && frac == 0)) { + ++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 strlen(str); + } + + int count = prec; + while (count > 0) { + --count; + *wstr++ = (char)(48 + (frac % 10)); + frac /= 10; + } + if (frac > 0) { + ++whole; + } + + /* add decimal */ + if (prec > 0) { + *wstr++ = '.'; + } + + /* do whole part + * Take care of sign conversion + * Number is reversed. + */ + do *wstr++ = (char)(48 + (whole % 10)); while (whole /= 10); + if (neg) { + *wstr++ = '-'; + } + *wstr='\0'; + strreverse(str, wstr-1); + return (size_t)(wstr - str); } @@ -190,116 +195,109 @@ size_t modp_dtoa(double value, char* str, int prec) */ size_t modp_dtoa2(double value, char* str, int prec) { - /* Hacky test for NaN - * under -fast-math this won't work, but then you also won't - * have correct nan values anyways. The alternative is - * to link with libmath (bad) or hack IEEE double bits (bad) - */ - if (! (value == value)) { - str[0] = 'n'; str[1] = 'a'; str[2] = 'n'; str[3] = '\0'; - return (size_t) 3; - } - - /* 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; - if (value < 0) { - neg = 1; - value = -value; - } - - - int whole = (int) value; - double tmp = (value - whole) * powers_of_10[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 >= powers_of_10[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; - } - - /* 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 strlen(str); - } - - if (prec == 0) { - diff = value - whole; - if (diff > 0.5) { - /* greater than 0.5, round up, e.g. 1.6 -> 2 */ - ++whole; - } else if (diff == 0.5 && (whole & 1)) { - /* exactly 0.5 and ODD, then round up */ - /* 1.5 -> 2, but 2.5 -> 2 */ - ++whole; - } - - /* vvvvvvvvvvvvvvvvvvv Diff from modp_dto2 */ - } else if (frac) { - count = prec; - /* - * now do fractional part, as an unsigned number - * we know it is not 0 but we can have leading zeros, these - * should be removed - */ - while (!(frac % 10)) { - --count; - frac /= 10; - } - /*^^^^^^^^^^^^^^^^^^^ Diff from modp_dto2 */ - - /* now do fractional part, as an unsigned number */ - do { - --count; - *wstr++ = (char)(48 + (frac % 10)); - } while (frac /= 10); - /* add extra 0s */ - while (count-- > 0) *wstr++ = '0'; - /* add decimal */ - *wstr++ = '.'; - } - - /* do whole part - * Take care of sign - * Conversion. Number is reversed. - */ - do *wstr++ = (char)(48 + (whole % 10)); while (whole /= 10); - if (neg) { - *wstr++ = '-'; - } - *wstr='\0'; - strreverse(str, wstr-1); - return (size_t)(wstr - str); + /* Hacky test for NaN + * under -fast-math this won't work, but then you also won't + * have correct nan values anyways. The alternative is + * to link with libmath (bad) or hack IEEE double bits (bad) + */ + if (! (value == value)) { + str[0] = 'n'; str[1] = 'a'; str[2] = 'n'; str[3] = '\0'; + return (size_t) 3; + } + + /* if input is larger than thres_max, revert to exponential */ + const double thres_max = (double)(0x7FFFFFFF); + + 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; + if (value < 0) { + neg = 1; + value = -value; + } + + int whole = (int) value; + double tmp = (value - whole) * powers_of_10[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 >= powers_of_10[prec]) { + frac = 0; + ++whole; + } + } else if (diff == 0.5 && ((frac & 1))) { + /* if halfway, round up if odd, OR + if last digit is 0. That last part is strange */ + ++frac; + if (frac >= powers_of_10[prec]) { + frac = 0; + ++whole; + } + } else if (diff == 0.5 && (prec > 0 && frac == 0)) { + ++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 strlen(str); + } + + int has_decimal = 0; + int count = prec; + + /* Remove ending zeros */ + if (prec > 0) { + while (count > 0 && ((frac % 10) == 0)) { + count--; + frac /= 10; + } + } + + while (count > 0) { + --count; + *wstr++ = (char)(48 + (frac % 10)); + frac /= 10; + has_decimal = 1; + } + + if (frac > 0) { + ++whole; + } + + /* add decimal */ + if (has_decimal) { + *wstr++ = '.'; + } + /* do whole part + * Take care of sign conversion + * Number is reversed. + */ + do *wstr++ = (char)(48 + (whole % 10)); while (whole /= 10); + if (neg) { + *wstr++ = '-'; + } + *wstr='\0'; + strreverse(str, wstr-1); + return (size_t)(wstr - str); } @@ -313,40 +311,40 @@ size_t modp_dtoa2(double value, char* str, int prec) char* modp_uitoa16(uint32_t value, char* str, int isfinal) { - static const char* hexchars = "0123456789ABCDEF"; - - /** - * Implementation note: - * No re-assignment of "value" - * Each line is independent than the previous, so - * even dumb compilers can pipeline without loop unrolling - */ + static const char* hexchars = "0123456789ABCDEF"; + + /** + * Implementation note: + * No re-assignment of "value" + * Each line is independent than the previous, so + * even dumb compilers can pipeline without loop unrolling + */ #ifndef WORDS_BIGENDIAN - /* x86 */ - str[0] = hexchars[(value >> 28) & 0x0000000F]; - str[1] = hexchars[(value >> 24) & 0x0000000F]; - str[2] = hexchars[(value >> 20) & 0x0000000F]; - str[3] = hexchars[(value >> 16) & 0x0000000F]; - str[4] = hexchars[(value >> 12) & 0x0000000F]; - str[5] = hexchars[(value >> 8) & 0x0000000F]; - str[6] = hexchars[(value >> 4) & 0x0000000F]; - str[7] = hexchars[(value ) & 0x0000000F]; + /* x86 */ + str[0] = hexchars[(value >> 28) & 0x0000000F]; + str[1] = hexchars[(value >> 24) & 0x0000000F]; + str[2] = hexchars[(value >> 20) & 0x0000000F]; + str[3] = hexchars[(value >> 16) & 0x0000000F]; + str[4] = hexchars[(value >> 12) & 0x0000000F]; + str[5] = hexchars[(value >> 8) & 0x0000000F]; + str[6] = hexchars[(value >> 4) & 0x0000000F]; + str[7] = hexchars[(value ) & 0x0000000F]; #else - /* sun, motorola, ibm */ - str[0] = hexchars[(value ) & 0x0000000F]; - str[1] = hexchars[(value >> 4) & 0x0000000F]; - str[2] = hexchars[(value >> 8) & 0x0000000F]; - str[3] = hexchars[(value >> 12) & 0x0000000F]; - str[4] = hexchars[(value >> 16) & 0x0000000F]; - str[5] = hexchars[(value >> 20) & 0x0000000F]; - str[6] = hexchars[(value >> 24) & 0x0000000F]; - str[7] = hexchars[(value >> 28) & 0x0000000F]; + /* sun, motorola, ibm */ + str[0] = hexchars[(value ) & 0x0000000F]; + str[1] = hexchars[(value >> 4) & 0x0000000F]; + str[2] = hexchars[(value >> 8) & 0x0000000F]; + str[3] = hexchars[(value >> 12) & 0x0000000F]; + str[4] = hexchars[(value >> 16) & 0x0000000F]; + str[5] = hexchars[(value >> 20) & 0x0000000F]; + str[6] = hexchars[(value >> 24) & 0x0000000F]; + str[7] = hexchars[(value >> 28) & 0x0000000F]; #endif - if (isfinal) { - str[8] = '\0'; - return str; - } else { - return str + 8; - } + if (isfinal) { + str[8] = '\0'; + return str; + } else { + return str + 8; + } } diff --git a/test/modp_numtoa_test.c b/test/modp_numtoa_test.c index 050a5ea..6efe292 100644 --- a/test/modp_numtoa_test.c +++ b/test/modp_numtoa_test.c @@ -18,208 +18,208 @@ static char* testITOA(void) { - char buf1[100]; - char buf2[100]; - int i; - size_t len; - for (i = 0; i < 100000; ++i) { - sprintf(buf1, "%d", i); - len = modp_itoa10(i, buf2); - mu_assert_int_equals(len, strlen(buf1)); - mu_assert_str_equals(buf1, buf2); - - sprintf(buf1, "%d", -i); - len = modp_itoa10(-i, buf2); - mu_assert_int_equals(len, strlen(buf1)); - mu_assert_str_equals(buf1, buf2); - - sprintf(buf1, "%d", INT_MAX - i); - len = modp_itoa10(INT_MAX - i, buf2); - mu_assert_int_equals(len, strlen(buf1)); - mu_assert_str_equals(buf1, buf2); - - sprintf(buf1, "%d", -(INT_MAX - i)); - len = modp_itoa10(-(INT_MAX - i), buf2); - mu_assert_int_equals(len, strlen(buf1)); - mu_assert_str_equals(buf1, buf2); - } - return 0; + char buf1[100]; + char buf2[100]; + int i; + size_t len; + for (i = 0; i < 100000; ++i) { + sprintf(buf1, "%d", i); + len = modp_itoa10(i, buf2); + mu_assert_int_equals(len, strlen(buf1)); + mu_assert_str_equals(buf1, buf2); + + sprintf(buf1, "%d", -i); + len = modp_itoa10(-i, buf2); + mu_assert_int_equals(len, strlen(buf1)); + mu_assert_str_equals(buf1, buf2); + + sprintf(buf1, "%d", INT_MAX - i); + len = modp_itoa10(INT_MAX - i, buf2); + mu_assert_int_equals(len, strlen(buf1)); + mu_assert_str_equals(buf1, buf2); + + sprintf(buf1, "%d", -(INT_MAX - i)); + len = modp_itoa10(-(INT_MAX - i), buf2); + mu_assert_int_equals(len, strlen(buf1)); + mu_assert_str_equals(buf1, buf2); + } + return 0; } static char* testUITOA(void) { - char buf1[100]; - char buf2[100]; - uint32_t i; - size_t len; - for (i = 0; i < 1000000; ++i) { - sprintf(buf1, "%u", i); - len = modp_uitoa10(i, buf2); - mu_assert_int_equals(len, strlen(buf1)); - mu_assert_str_equals(buf1, buf2); - } - - for (i = 0; i < 1000000; ++i) { - sprintf(buf1, "%u", 0xFFFFFFFFu - i); - len = modp_uitoa10(0xFFFFFFFFu -i, buf2); - mu_assert_int_equals(len, strlen(buf1)); - mu_assert_str_equals(buf1, buf2); - } - return 0; + char buf1[100]; + char buf2[100]; + uint32_t i; + size_t len; + for (i = 0; i < 1000000; ++i) { + sprintf(buf1, "%u", i); + len = modp_uitoa10(i, buf2); + mu_assert_int_equals(len, strlen(buf1)); + mu_assert_str_equals(buf1, buf2); + } + + for (i = 0; i < 1000000; ++i) { + sprintf(buf1, "%u", 0xFFFFFFFFu - i); + len = modp_uitoa10(0xFFFFFFFFu -i, buf2); + mu_assert_int_equals(len, strlen(buf1)); + mu_assert_str_equals(buf1, buf2); + } + return 0; } static char* testLITOA(void) { - char buf1[100]; - char buf2[100]; - long int i; - size_t len; - for (i = 0; i < 100000; ++i) { - sprintf(buf1, "%ld", i); - len = modp_litoa10(i, buf2); - mu_assert_int_equals(len, strlen(buf1)); - mu_assert_str_equals(buf1, buf2); - - sprintf(buf1, "%ld", -i); - len = modp_litoa10(-i, buf2); - mu_assert_int_equals(len, strlen(buf1)); - mu_assert_str_equals(buf1, buf2); - - sprintf(buf1, "%ld", LONG_MAX - i); - len = modp_litoa10(LONG_MAX - i, buf2); - mu_assert_int_equals(len, strlen(buf1)); - mu_assert_str_equals(buf1, buf2); - - sprintf(buf1, "%ld", -(LONG_MAX - i)); - len = modp_litoa10(-(LONG_MAX - i), buf2); - mu_assert_int_equals(len, strlen(buf1)); - mu_assert_str_equals(buf1, buf2); - } - return 0; + char buf1[100]; + char buf2[100]; + long int i; + size_t len; + for (i = 0; i < 100000; ++i) { + sprintf(buf1, "%ld", i); + len = modp_litoa10(i, buf2); + mu_assert_int_equals(len, strlen(buf1)); + mu_assert_str_equals(buf1, buf2); + + sprintf(buf1, "%ld", -i); + len = modp_litoa10(-i, buf2); + mu_assert_int_equals(len, strlen(buf1)); + mu_assert_str_equals(buf1, buf2); + + sprintf(buf1, "%ld", LONG_MAX - i); + len = modp_litoa10(LONG_MAX - i, buf2); + mu_assert_int_equals(len, strlen(buf1)); + mu_assert_str_equals(buf1, buf2); + + sprintf(buf1, "%ld", -(LONG_MAX - i)); + len = modp_litoa10(-(LONG_MAX - i), buf2); + mu_assert_int_equals(len, strlen(buf1)); + mu_assert_str_equals(buf1, buf2); + } + return 0; } static char* testULITOA(void) { - char buf1[100]; - char buf2[100]; - size_t len; - long long unsigned int i; - for (i = 0; i < 1000000; ++i) { - sprintf(buf1, "%llu", i); - len = modp_ulitoa10(i, buf2); - mu_assert_int_equals(len, strlen(buf1)); - mu_assert_str_equals(buf1, buf2); - } - - for (i = 0; i < 1000000; ++i) { - sprintf(buf1, "%llu", 0xFFFFFFFFFFFFFFFFllu - i); - len = modp_ulitoa10(0xFFFFFFFFFFFFFFFFull -i, buf2); - mu_assert_int_equals(len, strlen(buf1)); - mu_assert_str_equals(buf1, buf2); - } - return 0; + char buf1[100]; + char buf2[100]; + size_t len; + long long unsigned int i; + for (i = 0; i < 1000000; ++i) { + sprintf(buf1, "%llu", i); + len = modp_ulitoa10(i, buf2); + mu_assert_int_equals(len, strlen(buf1)); + mu_assert_str_equals(buf1, buf2); + } + + for (i = 0; i < 1000000; ++i) { + sprintf(buf1, "%llu", 0xFFFFFFFFFFFFFFFFllu - i); + len = modp_ulitoa10(0xFFFFFFFFFFFFFFFFull -i, buf2); + mu_assert_int_equals(len, strlen(buf1)); + mu_assert_str_equals(buf1, buf2); + } + return 0; } static char* testDoubleToA(void) { - char buf1[100]; - char buf2[100]; - char msg[200]; - double d; - size_t len; - char* tmp; - size_t tmplen; - - /* test each combination of whole number + fraction, - at every precision */ - /* and test negative version */ - double wholes[] = {0,1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0,11.0, - 67.0,101.0, 10000, 99999}; - double frac[] = {0.0, 0.1, 0.2, 0.3, 0.4, 0.49, 0.5, 0.51, 0.6, 0.7, - 0.9, 0.01, 0.25, 0.125, 0.05, 0.005, 0.0005, 0.00005, - 0.001, 0.00001, 0.99, 0.999, 0.9999, 0.99999, 0.999999, - 0.09, 0.099, 0.0999, 0.09999, 0.099999, 0.0999999, - 0.09999999 - }; - - - const char* formats[] = {"%.0f", "%.1f", "%.2f", "%.3f", "%.4f", "%.5f", - "%.6f", "%.7f", "%.8f", "%.9f"}; - - size_t imax = sizeof(wholes)/sizeof(double); - size_t jmax = sizeof(frac)/sizeof(double); - size_t kmax = sizeof(formats)/sizeof(const char*); - - size_t i,j,k; - for (i = 0; i < imax; ++i) { - for (j = 0; j < jmax; ++j) { - for (k = 0; k < kmax; ++k) { - d = wholes[i] + frac[j]; - - sprintf(msg, "whole=%f, frac=%f, prec=%d -- ", - wholes[i], frac[j],(int) k); - sprintf(buf1, formats[k], d); - len = modp_dtoa(d, buf2, (int)k); - mu_assert_int_equals(len, strlen(buf1)); - mu_assert_str_equals_msg(msg, buf1, buf2); - - if ((int)wholes[i] != 0 && (int)(frac[j]*10000000) != 0) { - sprintf(msg, "whole=%f, frac=%f, prec=%d -- ", - -wholes[i], frac[j], (int) k); - /* not dealing with "-0" issues */ - d = -d; - sprintf(buf1, formats[k], d); - len = modp_dtoa(d, buf2, (int)k); - mu_assert_int_equals(len, strlen(buf1)); - mu_assert_str_equals_msg(msg, buf1, buf2); - - /* find the '.', and see how many chars are after it */ - tmp = buf2; - while (*tmp != '.' && *tmp != '\0') { - ++tmp; - } - if (*tmp == '\0') { - tmplen = 0; - } else { - tmplen = strlen(++tmp); - } - - sprintf(msg, "whole=%f, frac=%f, prec=%d, got=%d %s-- ", - wholes[i], frac[j], (int)k, (int)tmplen, buf2); - mu_assert_msg(msg, k >= tmplen); - - } - } - } - } - - /* test very large positive number */ - d = 1.0e200; - len = modp_dtoa(d, buf2, 6); - mu_assert_int_equals(len, strlen(buf2)); - mu_assert_str_equals("1.000000e+200", buf2); - - /* test very large negative number */ - d = -1.0e200; - len = modp_dtoa(d, buf2, 6); - mu_assert_int_equals(len, strlen(buf2)); - mu_assert_str_equals("-1.000000e+200", buf2); - - /* test very small positive number */ - d = 1e-10; - sprintf(buf1, "%.6f", d); - len = modp_dtoa(d, buf2, 6); - mu_assert_int_equals(len, strlen(buf1)); - mu_assert_str_equals(buf1, buf2); - - /* test very small negative number */ - d = -1e-10; - sprintf(buf1, "%.6f", d); - len = modp_dtoa(d, buf2, 6); - mu_assert_int_equals(len, strlen(buf1)); - mu_assert_str_equals(buf1, buf2); - - return 0; + char buf1[100]; + char buf2[100]; + char msg[200]; + double d; + size_t len; + char* tmp; + size_t tmplen; + + /* test each combination of whole number + fraction, + at every precision */ + /* and test negative version */ + double wholes[] = {0,1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0,11.0, + 67.0,101.0, 10000, 99999}; + double frac[] = {0.0, 0.1, 0.2, 0.3, 0.4, 0.49, 0.5, 0.51, 0.6, 0.7, + 0.9, 0.01, 0.25, 0.125, 0.03, 0.05, 0.005, 0.0005, 0.00005, + 0.001, 0.00001, 0.99, 0.999, 0.9999, 0.99999, 0.999999, + 0.09, 0.099, 0.0999, 0.09999, 0.099999, 0.0999999, + 0.09999999 + }; + + + const char* formats[] = {"%.0f", "%.1f", "%.2f", "%.3f", "%.4f", "%.5f", + "%.6f", "%.7f", "%.8f", "%.9f"}; + + size_t imax = sizeof(wholes)/sizeof(double); + size_t jmax = sizeof(frac)/sizeof(double); + size_t kmax = sizeof(formats)/sizeof(const char*); + + size_t i,j,k; + for (i = 0; i < imax; ++i) { + for (j = 0; j < jmax; ++j) { + for (k = 0; k < kmax; ++k) { + d = wholes[i] + frac[j]; + + sprintf(buf1, formats[k], d); + sprintf(msg, "orig=%f whole=%f, frac=%f, prec=%d -- want %s", + wholes[i] + frac[j], wholes[i], frac[j],(int) k, buf1); + len = modp_dtoa(d, buf2, (int)k); + mu_assert_str_equals_msg(msg, buf1, buf2); + mu_assert_int_equals(len, strlen(buf1)); + + if ((int)wholes[i] != 0 && (int)(frac[j]*10000000) != 0) { + sprintf(msg, "whole=%f, frac=%f, prec=%d -- ", + -wholes[i], frac[j], (int) k); + /* not dealing with "-0" issues */ + d = -d; + sprintf(buf1, formats[k], d); + len = modp_dtoa(d, buf2, (int)k); + mu_assert_int_equals(len, strlen(buf1)); + mu_assert_str_equals_msg(msg, buf1, buf2); + + /* find the '.', and see how many chars are after it */ + tmp = buf2; + while (*tmp != '.' && *tmp != '\0') { + ++tmp; + } + if (*tmp == '\0') { + tmplen = 0; + } else { + tmplen = strlen(++tmp); + } + + sprintf(msg, "whole=%f, frac=%f, prec=%d, got=%d %s-- ", + wholes[i], frac[j], (int)k, (int)tmplen, buf2); + mu_assert_msg(msg, k >= tmplen); + + } + } + } + } + + /* test very large positive number */ + d = 1.0e200; + len = modp_dtoa(d, buf2, 6); + mu_assert_int_equals(len, strlen(buf2)); + mu_assert_str_equals("1.000000e+200", buf2); + + /* test very large negative number */ + d = -1.0e200; + len = modp_dtoa(d, buf2, 6); + mu_assert_int_equals(len, strlen(buf2)); + mu_assert_str_equals("-1.000000e+200", buf2); + + /* test very small positive number */ + d = 1e-10; + sprintf(buf1, "%.6f", d); + len = modp_dtoa(d, buf2, 6); + mu_assert_int_equals(len, strlen(buf1)); + mu_assert_str_equals(buf1, buf2); + + /* test very small negative number */ + d = -1e-10; + sprintf(buf1, "%.6f", d); + len = modp_dtoa(d, buf2, 6); + mu_assert_int_equals(len, strlen(buf1)); + mu_assert_str_equals(buf1, buf2); + + return 0; } /* Helper function @@ -228,284 +228,281 @@ static char* testDoubleToA(void) */ static void stripTrailingZeros(char* buf) { - size_t i; - int hasdot = 0; - for (i = 0; i < strlen(buf); ++i) { - if (buf[i] == '.') { - hasdot = 1; - break; - } - } - - /* it's just an integer */ - if (!hasdot) { - return; - } - - i = strlen(buf); - if (i == 0) { - return; - } - --i; - - while (i > 0 && (buf[i] == '0' || buf[i] == '.')) { - if (buf[i] == '.') { - buf[i] = '\0'; - break; - } else { - buf[i] = '\0'; - --i; - } - } + size_t i; + int hasdot = 0; + for (i = 0; i < strlen(buf); ++i) { + if (buf[i] == '.') { + hasdot = 1; + break; + } + } + + /* it's just an integer */ + if (!hasdot) { + return; + } + + i = strlen(buf); + if (i == 0) { + return; + } + --i; + + while (i > 0 && (buf[i] == '0' || buf[i] == '.')) { + if (buf[i] == '.') { + buf[i] = '\0'; + break; + } else { + buf[i] = '\0'; + --i; + } + } } static char* testDoubleToA2(void) { - char buf1[100]; - char buf2[100]; - char msg[200]; - double d; - - char* tmp; - size_t len; - size_t tmplen; - - /* test each combination of whole number + fraction, - at every precision */ - /* and test negative version */ - double wholes[] = {0,1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0,11.0, - 67.0,101.0, 10000, 99999}; - double frac[] = {0.0, 0.1, 0.2, 0.3, 0.4, 0.49, 0.5, 0.51, 0.6, 0.7, - 0.9, 0.01, 0.25, 0.125, 0.05, 0.005, 0.0005, 0.00005, - 0.001, 0.00001, 0.99, 0.999, 0.9999, 0.99999, 0.999999, - 0.09, 0.099, 0.0999, 0.09999, 0.099999, 0.0999999, - 0.09999999 - }; - const char* formats[] = {"%.0f", "%.1f", "%.2f", "%.3f", "%.4f", "%.5f", - "%.6f", "%.7f", "%.8f", "%.9f"}; - - int imax = sizeof(wholes)/sizeof(double); - int jmax = sizeof(frac)/sizeof(double); - int kmax = sizeof(formats)/sizeof(const char*); - - int i,j,k; - for (i = 0; i < imax; ++i) { - for (j = 0; j < jmax; ++j) { - for (k = 0; k < kmax; ++k) { - d = wholes[i] + frac[j]; - - sprintf(msg, "whole=%f, frac=%f, prec=%d -- ", - wholes[i], frac[j], k); - - sprintf(buf1, formats[k], d); - stripTrailingZeros(buf1); - len = modp_dtoa2(d, buf2, k); - - if ((int)wholes[i] != 0 && (int)(frac[j]*10000000) != 0) { - - /* find the '.', and see how many chars are after it */ - tmp = buf2; - while (*tmp != '.' && *tmp != '\0') { - ++tmp; - } - if (*tmp == '\0') { - tmplen = 0; - } else { - tmplen = strlen(++tmp); - } - - sprintf(msg, "whole=%f, frac=%f, prec=%d, got=%d %s-- ", - wholes[i], frac[j], k, (int)tmplen, buf2); - mu_assert_msg(msg, (size_t)k >= tmplen); - - mu_assert_str_equals_msg(msg, buf1, buf2); - - sprintf(msg, "whole=%f, frac=%f, prec=%d -- ", - -wholes[i], frac[j], k); - /* not dealing with "-0" issues */ - d = -d; - sprintf(buf1, formats[k], d); - stripTrailingZeros(buf1); - - len = modp_dtoa2(d, buf2, k); - mu_assert_int_equals(len, strlen(buf2)); - mu_assert_str_equals_msg(msg, buf1, buf2); - } - - } - } - } - - /* test very large positive number */ - d = 1.0e200; - len = modp_dtoa2(d, buf2, 6); - mu_assert_int_equals(len, strlen(buf2)); - mu_assert_str_equals("1.000000e+200", buf2); - - /* test very large negative number */ - d = -1.0e200; - len = modp_dtoa2(d, buf2, 6); - mu_assert_int_equals(len, strlen(buf2)); - mu_assert_str_equals("-1.000000e+200", buf2); - - /* test very small positive number */ - d = 1e-10; - sprintf(buf1, "%.6f", d); - stripTrailingZeros(buf1); - - len = modp_dtoa2(d, buf2, 6); - mu_assert_int_equals(len, strlen(buf2)); - mu_assert_str_equals(buf1, buf2); - - /* test very small negative number */ - d = -1e-10; - sprintf(buf1, "%.6f", d); - stripTrailingZeros(buf1); - - len = modp_dtoa2(d, buf2, 6); - mu_assert_int_equals(len, strlen(buf2)); - mu_assert_str_equals(buf1, buf2); - - /* test bad precision values */ - d = 1.1; - len = modp_dtoa(d, buf2, -1); - mu_assert_int_equals(len, strlen(buf2)); - mu_assert_str_equals("1", buf2); - len = modp_dtoa2(d, buf2, 10); - mu_assert_int_equals(len, strlen(buf2)); - mu_assert_str_equals("1.1", buf2); - return 0; + char buf1[100]; + char buf2[100]; + char msg[200]; + double d; + + char* tmp; + size_t len; + size_t tmplen; + + /* test each combination of whole number + fraction, + at every precision */ + /* and test negative version */ + double wholes[] = {0,1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0,11.0, + 67.0,101.0, 10000, 99999}; + double frac[] = {0.0, 0.1, 0.2, 0.3, 0.4, 0.49, 0.5, 0.51, 0.6, 0.7, + 0.9, 0.01, 0.25, 0.125, 0.05, 0.005, 0.0005, 0.00005, + 0.001, 0.00001, 0.99, 0.999, 0.9999, 0.99999, 0.999999, + 0.09, 0.099, 0.0999, 0.09999, 0.099999, 0.0999999, + 0.09999999 + }; + const char* formats[] = {"%.0f", "%.1f", "%.2f", "%.3f", "%.4f", "%.5f", + "%.6f", "%.7f", "%.8f", "%.9f"}; + + int imax = sizeof(wholes)/sizeof(double); + int jmax = sizeof(frac)/sizeof(double); + int kmax = sizeof(formats)/sizeof(const char*); + + int i,j,k; + for (i = 0; i < imax; ++i) { + for (j = 0; j < jmax; ++j) { + for (k = 0; k < kmax; ++k) { + d = wholes[i] + frac[j]; + + sprintf(msg, "whole=%f, frac=%f, prec=%d -- ", + wholes[i], frac[j], k); + + sprintf(buf1, formats[k], d); + stripTrailingZeros(buf1); + len = modp_dtoa2(d, buf2, k); + + if ((int)wholes[i] != 0 && (int)(frac[j]*10000000) != 0) { + + /* find the '.', and see how many chars are after it */ + tmp = buf2; + while (*tmp != '.' && *tmp != '\0') { + ++tmp; + } + if (*tmp == '\0') { + tmplen = 0; + } else { + tmplen = strlen(++tmp); + } + + sprintf(msg, "orig=%f whole=%f, frac=%f, prec=%d -- want %s", + wholes[i] + frac[j], wholes[i], frac[j],(int) k, buf1); + mu_assert_str_equals_msg(msg, buf1, buf2); + mu_assert_msg(msg, (size_t)k >= tmplen); + + /* not dealing with "-0" issues */ + d = -d; + sprintf(buf1, formats[k], d); + stripTrailingZeros(buf1); + + len = modp_dtoa2(d, buf2, k); + mu_assert_int_equals(len, strlen(buf2)); + mu_assert_str_equals_msg(msg, buf1, buf2); + } + + } + } + } + + /* test very large positive number */ + d = 1.0e200; + len = modp_dtoa2(d, buf2, 6); + mu_assert_int_equals(len, strlen(buf2)); + mu_assert_str_equals("1.000000e+200", buf2); + + /* test very large negative number */ + d = -1.0e200; + len = modp_dtoa2(d, buf2, 6); + mu_assert_int_equals(len, strlen(buf2)); + mu_assert_str_equals("-1.000000e+200", buf2); + + /* test very small positive number */ + d = 1e-10; + sprintf(buf1, "%.6f", d); + stripTrailingZeros(buf1); + + len = modp_dtoa2(d, buf2, 6); + mu_assert_int_equals(len, strlen(buf2)); + mu_assert_str_equals(buf1, buf2); + + /* test very small negative number */ + d = -1e-10; + sprintf(buf1, "%.6f", d); + stripTrailingZeros(buf1); + + len = modp_dtoa2(d, buf2, 6); + mu_assert_int_equals(len, strlen(buf2)); + mu_assert_str_equals(buf1, buf2); + + /* test bad precision values */ + d = 1.1; + len = modp_dtoa(d, buf2, -1); + mu_assert_int_equals(len, strlen(buf2)); + mu_assert_str_equals("1", buf2); + len = modp_dtoa2(d, buf2, 10); + mu_assert_int_equals(len, strlen(buf2)); + mu_assert_str_equals("1.1", buf2); + return 0; } /* From Issue 7 -- http://code.google.com/p/stringencoders/issues/detail?id=7 * thanks to http://code.google.com/u/simhasana/ */ static char* testOverflowLITOA(void) { - char buf1[100]; - char buf2[100]; + char buf1[100]; + char buf2[100]; - long long int longmin = LONG_MIN; - sprintf(buf1, "%lld", longmin); - modp_litoa10(longmin, buf2); - mu_assert_str_equals(buf1, buf2); + long long int longmin = LONG_MIN; + sprintf(buf1, "%lld", longmin); + modp_litoa10(longmin, buf2); + mu_assert_str_equals(buf1, buf2); - long long int longmax = LONG_MAX; - sprintf(buf1, "%lld", longmax); - modp_litoa10(longmax, buf2); - mu_assert_str_equals(buf1, buf2); + long long int longmax = LONG_MAX; + sprintf(buf1, "%lld", longmax); + modp_litoa10(longmax, buf2); + mu_assert_str_equals(buf1, buf2); - return 0; + return 0; } static char* testOverflowITOA(void) { - char buf1[100]; - char buf2[100]; + char buf1[100]; + char buf2[100]; - int32_t intmin = INT_MIN; - sprintf(buf1, "%d", intmin); - modp_itoa10(intmin, buf2); - mu_assert_str_equals(buf1, buf2); + int32_t intmin = INT_MIN; + sprintf(buf1, "%d", intmin); + modp_itoa10(intmin, buf2); + mu_assert_str_equals(buf1, buf2); - int32_t intmax = INT_MAX; - sprintf(buf1, "%d", intmax); - modp_itoa10(intmax, buf2); - mu_assert_str_equals(buf1, buf2); + int32_t intmax = INT_MAX; + sprintf(buf1, "%d", intmax); + modp_itoa10(intmax, buf2); + mu_assert_str_equals(buf1, buf2); - return 0; + return 0; } /* Test NaN and Infinity behavior */ static char* testDTOANonFinite(void) { - char buf2[100]; - double d; - - /* Test for inf */ - d = 1e200 * 1e200; - /* NOTE!!! next line will core dump! - * sprintf(buf1, "%.6f", d); - */ - buf2[0] = '\0'; - modp_dtoa2(d, buf2, 6); - mu_assert_str_equals("inf", buf2); - return 0; + char buf2[100]; + double d; + + /* Test for inf */ + d = 1e200 * 1e200; + /* NOTE!!! next line will core dump! + * sprintf(buf1, "%.6f", d); + */ + buf2[0] = '\0'; + modp_dtoa2(d, buf2, 6); + mu_assert_str_equals("inf", buf2); + return 0; } static char* testDTOAInfinity(void) { - /* INFINITY should be standard. Defined in */ - /* http://www.gnu.org/s/libc/manual/html_node/Infinity-and-NaN.html */ + /* INFINITY should be standard. Defined in */ + /* http://www.gnu.org/s/libc/manual/html_node/Infinity-and-NaN.html */ #ifdef INFINITY - char buf1[100]; - char buf2[100]; - double d = INFINITY; + char buf1[100]; + char buf2[100]; + double d = INFINITY; - /* test libc support */ - sprintf(buf1, "%f", d); - mu_assert_str_equals("inf", buf1); + /* test libc support */ + sprintf(buf1, "%f", d); + mu_assert_str_equals("inf", buf1); - buf2[0] = '\0'; - modp_dtoa(d, buf2, 6); - mu_assert_str_equals("inf", buf2); + buf2[0] = '\0'; + modp_dtoa(d, buf2, 6); + mu_assert_str_equals("inf", buf2); - buf2[0] = '\0'; - modp_dtoa2(d, buf2, 6); - mu_assert_str_equals("inf", buf2); + buf2[0] = '\0'; + modp_dtoa2(d, buf2, 6); + mu_assert_str_equals("inf", buf2); #endif - return 0; + return 0; } static char* testDTOAandNAN(void) { - /* NAN is a GNU extension, defined in */ - /* http://www.gnu.org/s/libc/manual/html_node/Infinity-and-NaN.html */ + /* NAN is a GNU extension, defined in */ + /* http://www.gnu.org/s/libc/manual/html_node/Infinity-and-NaN.html */ #ifdef NAN - char buf1[100]; - char buf2[100]; - double d; - - d = NAN; - - /* test libc support */ - sprintf(buf1, "%f", d); - mu_assert_str_equals("nan", buf1); - - /* now test ours */ - buf2[0] = '\0'; - modp_dtoa(d, buf2, 6); - mu_assert_str_equals("nan", buf2); - buf2[0] = '\0'; - modp_dtoa2(d, buf2, 6); - mu_assert_str_equals("nan", buf2); + char buf1[100]; + char buf2[100]; + double d; + + d = NAN; + + /* test libc support */ + sprintf(buf1, "%f", d); + mu_assert_str_equals("nan", buf1); + + /* now test ours */ + buf2[0] = '\0'; + modp_dtoa(d, buf2, 6); + mu_assert_str_equals("nan", buf2); + buf2[0] = '\0'; + modp_dtoa2(d, buf2, 6); + mu_assert_str_equals("nan", buf2); #endif - return 0; + return 0; } static char* testUITOA16(void) { - char buf1[100]; - char buf2[100]; + char buf1[100]; + char buf2[100]; - modp_uitoa16(1, buf1, 1); - mu_assert_str_equals(buf1, "00000001"); + modp_uitoa16(1, buf1, 1); + mu_assert_str_equals(buf1, "00000001"); - modp_uitoa16(0, buf1, 1); - mu_assert_str_equals(buf1, "00000000"); + modp_uitoa16(0, buf1, 1); + mu_assert_str_equals(buf1, "00000000"); - modp_uitoa16(0xFFFFFFFF, buf1, 1); - mu_assert_str_equals(buf1, "FFFFFFFF"); + modp_uitoa16(0xFFFFFFFF, buf1, 1); + mu_assert_str_equals(buf1, "FFFFFFFF"); - unsigned int i; - for (i = 1; i < 1000000; ++i) { - sprintf(buf1, "%08X", i); - modp_uitoa16(i, buf2, 1); - mu_assert_str_equals(buf1, buf2); - } - return 0; + unsigned int i; + for (i = 1; i < 1000000; ++i) { + sprintf(buf1, "%08X", i); + modp_uitoa16(i, buf2, 1); + mu_assert_str_equals(buf1, buf2); + } + return 0; } /** @@ -513,30 +510,30 @@ static char* testUITOA16(void) * http://code.google.com/p/stringencoders/issues/detail?id=15 */ static char* testRoundingPrecisionOverflow(void) { - char buf1[100]; + char buf1[100]; - modp_dtoa(0.09999999, buf1, 6); - mu_assert_str_equals(buf1, "0.100000"); - modp_dtoa2(0.09999999, buf1, 6); - mu_assert_str_equals(buf1, "0.1"); - return 0; + modp_dtoa(0.09999999, buf1, 6); + mu_assert_str_equals(buf1, "0.100000"); + modp_dtoa2(0.09999999, buf1, 6); + mu_assert_str_equals(buf1, "0.1"); + return 0; } static char* all_tests(void) { - mu_run_test(testITOA); - mu_run_test(testUITOA); - mu_run_test(testLITOA); - mu_run_test(testULITOA); - mu_run_test(testDoubleToA); - mu_run_test(testDoubleToA2); - mu_run_test(testOverflowLITOA); - mu_run_test(testOverflowITOA); - mu_run_test(testDTOANonFinite); - mu_run_test(testDTOAInfinity); - mu_run_test(testDTOAandNAN); - mu_run_test(testUITOA16); - mu_run_test(testRoundingPrecisionOverflow); - return 0; + mu_run_test(testITOA); + mu_run_test(testUITOA); + mu_run_test(testLITOA); + mu_run_test(testULITOA); + mu_run_test(testDoubleToA); + mu_run_test(testDoubleToA2); + mu_run_test(testOverflowLITOA); + mu_run_test(testOverflowITOA); + mu_run_test(testDTOANonFinite); + mu_run_test(testDTOAInfinity); + mu_run_test(testDTOAandNAN); + mu_run_test(testUITOA16); + mu_run_test(testRoundingPrecisionOverflow); + return 0; } UNITTESTS