首页 > 解决方案 > 我需要在不使用 INT32_MAX、INT_MAX 等常量的情况下找到最大 int32_t 数

问题描述

所以我有一个任务是在添加两个 int32_t 数字时检查溢出。如果发生溢出,我的函数必须返回最大或最小 int32_t 数,具体取决于溢出的符号,但使用 UINT32_MAX 等常量是受限制的。我怎么做?如果对您有帮助,请参考以下代码:

#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;
    }
}

标签: cintegeroverflowint32uint32-t

解决方案


INT32_MAX(maximum value of )int32_tINT32_MIN(minimum value of int32_t) 的值在 C 规范中定义,因此您可以编写值而不是使用常量。

引自N1570 7.20.2.1 精确宽度整数类型的限制:

— 精确宽度有符号整数类型的
最小值 INTN_MIN 精确 -(2 N-1 )
— 精确宽度有符号整数类型
INTN_MAX 的最大值 精确 2 N−1 - 1
— 精确宽度无符号整数类型
UINTN_MAX 的最大值 精确 2 N - 1

这里有一点: 2 N可以表示为1<<N,但1<<31会导致溢出,所以应该使用((1<<30)-1)*2+1代替1<<31

此外,您应该使用INT32_Cmacor 来使用文字 ofint32_t而不是int.

总之,您应该使用的是:

  • 的最大值int32_t((INT32_C(1)<<30)-1)*2+1
  • 的最小值int32_t-((INT32_C(1)<<30)-1)*2-2

推荐阅读