I need to find maximum int32_t number without using constants like INT32_MAX, INT_MAX, etc

1k Views Asked by At

So I have a task to check for overflow when adding two int32_t numbers. In case of overflow my function must return maximum or minimum number of int32_t, depending on the sign of overflow, but using constants like UINT32_MAX is restricted. How do I do that? Here's the code if it will help you:

#include "inttypes.h"

int32_t
satsum(int32_t v1, int32_t v2) {
    int32_t res = 0;
    if(__builtin_sadd_overflow(v1, v2, &res)) {
        if (res < 0) {
            return ?
        }
        return ?
    } else {
        res = v1 + v2;
        return res;
    }
}
2

There are 2 best solutions below

0
MikeCAT On BEST ANSWER

The value of INT32_MAX (maximum value of int32_t) and INT32_MIN (minimum value of int32_t) are defined in C specification, so you can write the values instead of using the constants.

Quote from N1570 7.20.2.1 Limits of exact-width integer types:

— minimum values of exact-width signed integer types
INTN_MIN exactly −(2N-1)
— maximum values of exact-width signed integer types
INTN_MAX exactly 2N−1 − 1
— maximum values of exact-width unsigned integer types
UINTN_MAX exactly 2N − 1

Here is one point: 2N can be represented as 1<<N, but 1<<31 will cause overflow, so you should use ((1<<30)-1)*2+1 instead of 1<<31.

Also you should use INT32_C macor to use literals of int32_t instead of int.

In conclusion, what you should use are:

  • The maximum value of int32_t: ((INT32_C(1)<<30)-1)*2+1
  • The minimum value of int32_t: -((INT32_C(1)<<30)-1)*2-2
3
Lundin On

int32_t is guaranteed to be in 2's complement form. This means that the maximum value is guaranteed to be 2^31 -1 and the minimum value is guaranteed to be -2^31.

So you can simply do this:

const int32_t i32_min = 1u << 31;
const int32_t i32_max = (1u << 31)-1u;

This code will cause implementation-defined conversions from unsigned to signed, which in this case means the conversion will have a 2's complement format.