The absolute value of INT_MIN

How can I extract the absolute value of INT_MIN without overflow? See this code for the problem:

 #include <limits.h> #include <stdio.h> #include <stdlib.h> int main(void) { printf("INT_MAX: %d\n", INT_MAX); printf("INT_MIN: %d\n", INT_MIN); printf("abs(INT_MIN): %d\n", abs(INT_MIN)); return 0; } 

Spits out the following

 INT_MAX: 2147483647 INT_MIN: -2147483648 abs(INT_MIN): -2147483648 

I need this to check if the int value is greater than zero.

Regarding this duplicate question. Why is the absolute value of the maximum negative integer -2147483648 so far equal to -2147483648? I must disagree, as this is HOW, and not WHY the question.

+8
c int integer-overflow
source share
6 answers

The conversion specifier %d in the printf format printf converts the corresponding argument to a signed decimal integer, which in this case overflows for the int type. The C standard mentions that counter integer overflows are undefined behavior. You should use %u in the format string. In addition, you need to include the stdio.h and stdlib.h headers for the prototype printf and abs functions respectively.

 #include <limits.h> #include <stdio.h> #include <stdlib.h> // This solves the issue of using the standard abs() function unsigned int absu(int value) { return (value < 0) ? -((unsigned int)value) : (unsigned int)value; } int main(void) { printf("INT_MAX: %d\n", INT_MAX); printf("INT_MIN: %d\n", INT_MIN); printf("absu(INT_MIN): %u\n", absu(INT_MIN)); return 0; } 

This gives the result on my 32 bit machine:

 INT_MAX: 2147483647 INT_MIN: -2147483648 abus(INT_MIN): 2147483648 
+2
source share

What about

 printf ("abs(INT_MIN) = %ld", -((long int) INT_MIN)); 

Or if your long no longer than int :

 printf ("abs(INT_MIN) = %lld", -((long long int) INT_MIN)); 

Or, if you are ready to accept that abs(INT_MIN) always INT_MAX + 1 :

 printf ("abs(INT_MIN) = %u", ((unsigned int) INT_MAX ) + 1 ); 
+2
source share

There is no figurative way to extract the absolute value of the largest negative number as a whole. The ISO C standard states (Β§6.2.6.2ΒΆ2):

Each bit, which is a value bit, must have the same value as one bit in the object representing the corresponding unsigned type (if in the signed type and N in the unsigned type, then M ≀ N).

Note that it uses ≀, not <.

Since the sign bit in 2 additions has a value of - (2 M ), and each bit of value has a value equal to two between 1 and 2 M-1 there is no unsigned integer in implementations where M = N can represent 2 N it can only represent up to 2 N -1 = 1 + 2 + ... + 2 N-1 .

+2
source share

In C, for the function int abs(int j) there is only an int version. You can use another labs function under the heading stdlib.h . Its prototype: long int labs(long int j);

 #include <limits.h> #include <stdio.h> #include <stdlib.h> int main(void) { printf("INT_MAX: %d\n", INT_MAX); printf("INT_MIN: %d\n", INT_MIN); printf("abs(INT_MIN): %ld\n", labs((long)INT_MIN)); return 0; } 
0
source share

To do this, make access to the next available larger integer type. but you must use the abs-correspondent option (in this case llabs(...) )

 printf("llabs(INT_MIN): %lld\n", llabs((long long int)INT_MIN)); 

change

you can check which next higher type by comparing INT_MIN with LONG_MIN and LLONG_MIN . Perhaps in your case, listing in long will already be done.

 printf("labs(INT_MIN): %ld\n", labs((long int)INT_MIN)); 

Note that explicit casts are not really needed, since the function itself will cast the argument implicitly

0
source share

First of all, you need #include <math.h> to use the abs function correctly.

Secondly, if the only thing you want to achieve is to print the absolute value INT_MIN defined in limits.h , you can simply print it as an unsigned integer or as a long long integer , for example:

 printf( "abs(INT_MIN): %u\n", abs( INT_MIN ) ); // %u for unsigned int printf( "abs(INT_MIN): %lld\n", abs( INT_MIN ) ); // %lld for long long int 

Since you want to have an absolute value that will definitely be unsigned, this should be ok.

If you do not want to include math.h , you can do it yourself:

 // ternary implementation of the function abs printf( "abs(INT_MIN): %u\n", ( INT_MIN > 0 ) ? INT_MIN : -INT_MIN ); 

If you want to use it for other purposes, you can store the abs( INT_MIN ) value abs( INT_MIN ) in unsigned int or long long int variables.

-one
source share

All Articles