I am not allowed to use abs or any other libraries. Here is what I've tried so far.
#include <stdio.h>
#include <limits.h>
int main()
{
int n = INT_MIN;
if (n == INT_MIN)
{
int a = -n;
a = n % 10;
putchar(a '0');
}
return (0);
}
The output is always "(" and not the correct answer.
CodePudding user response:
Apply modulus to the negative number first to get a single negative digit. Negate that.
#include <stdio.h>
#include <limits.h>
int main()
{
int n = INT_MIN;
int a = -( n % 10);
putchar(a '0');
return (0);
}
CodePudding user response:
When n == INT_MIN
, do not use a = -n
as that is undefined behavior (UB) since -n
overflows int
math.
Using a = n
will result in some value [-9 ... 0] since n < 0
. No need to negate a
before using it to print the digit, just subtract.
int n = INT_MIN;
int a = n;
putchar('0' - a);
To print the entire int
, note that there are more negative values [INT_MIN ... -1]
then positive ones [1 ... INT_MAX]
*1. Instead of negating negative numbers to positives (and have UB with INT_MIN
), negate positive ones to the negative side.
#include <limits.h>
#include <stdio.h>
...
int n = {some value from INT_MIN to INT_MAX};
int a = n < 0 ? n : -n;
char buf[21];
char *p = buf sizeof buf - 1;
*p = '\0';
do {
p--;
*p = '0' - a;
a /= 10;
} while (a);
if (n < 0) {
*--p = '-';
}
puts(p);
This approach works even if instead of int
, we used long long
or intmax_t
. We just need to adjust the buffer length. char buf[21]
big enough for 64-bit integers.
*1 With the common 2's complement integer encoding, there is always one more negative. With the rare 1s' complement and sign-magnitude encoding, likely to be dropped in C2x, there are the same. Of course with those there may be a 0 and -0, yet let us leave that for historic programming.