c语言 - 我需要在不使用 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;
}
}
INT32_MAX

(最大值为int32_t)和INT32_MIN(最小值int32_t)的值在 C 规范中定义,因此您可以编写值而不是使用常量。

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

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

INTN_MAX正好 2 N−1 − 1>— 精确宽度无符号整数类型的最大值
UINTN_MAX正好 2N1

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

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

总之,您应该使用的是:

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

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

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

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

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

相关内容

最新更新