diff --git a/lib/mes/ntoab.c b/lib/mes/ntoab.c index a83b4d31..25780652 100644 --- a/lib/mes/ntoab.c +++ b/lib/mes/ntoab.c @@ -20,6 +20,10 @@ #include #include +#include + +#define STR(x) #x +#define XSTR(s) STR(s) char * ntoab (long x, int base, int signed_p) @@ -34,7 +38,26 @@ ntoab (long x, int base, int signed_p) if (signed_p && x < 0) { sign_p = 1; - u = -x; + if (x == LONG_MIN) + { + /* Cannot do u = (-x), so avoid it. */ + long i; + if (base == 10) + return XSTR(LONG_MIN); + /* We cause the same result as + i = (-x) % base + u = (-x) / base + would in mathematics if x and base were integers. + It will be the case that -base < x <= 0 after the loop. + Because base > 1, the quotient will definitely fit into u. + i will contain the last digit to print. */ + for (u = 0; x <= -base; x += base, ++u) + ; + i = -x; + *p-- = i > 9 ? 'a' + i - 10 : '0' + i; + } + else + u = -x; } else u = x; diff --git a/lib/tests/scaffold/60-math.c b/lib/tests/scaffold/60-math.c index 76e55092..24830e5b 100644 --- a/lib/tests/scaffold/60-math.c +++ b/lib/tests/scaffold/60-math.c @@ -196,6 +196,9 @@ ok1: if (strcmp ("-2147483648", itoa (i))) return 34; + if (strcmp ("-80000000", ntoab (i, 16, 1))) + return 35; + oputs ("t: i = -2147483647\n"); i = -2147483647;