1

所以我有一个任务是在添加两个 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;
    }
}
4

2 回答 2

1

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
于 2020-11-13T13:16:07.337 回答
-1

int32_t保证是 2 的补码形式。这意味着最大值保证为 2^31 -1,最小值保证为 -2^31。

所以你可以简单地这样做:

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

此代码将导致实现定义的从无符号到有符号的转换,在这种情况下,这意味着转换将具有 2 的补码格式。

于 2020-11-13T13:56:35.890 回答