gpt4 book ai didi

c++ - 如何便携地找出 min(INT_MAX, and(INT_MIN))?

转载 作者:IT老高 更新时间:2023-10-28 12:43:17 25 4
gpt4 key购买 nike

我怎样才能便携地找出 INT_MAX 和 abs(INT_MIN) 中的最小值? (这是 INT_MIN 的数学绝对值,而不是对 abs 函数的调用。)

它应该与大多数系统中的 INT_MAX 相同,但我正在寻找一种更便携的方式。

最佳答案

典型值为INT_MIN为-2147483648,典型值为INT_MAX是2147483647,标准不保证。 TL;DR:您要搜索的值是 INT_MAX在符合要求的实现中。但是计算 min(INT_MAX, abs(INT_MIN))不便携。


INT_MIN 的可能值和 INT_MAX

INT_MININT_MAX由附件 E(实现限制)1 定义(C 标准,C++ 继承了这些东西):

The contents of the header are given below, in alphabetical order. The minimum magnitudes shown shall be replaced by implementation-defined magnitudes with the same sign. The values shall all be constant expressions suitable for use in #if preprocessing directives. The components are described further in 5.2.4.2.1.

[...]

#define INT_MAX +32767

#define INT_MIN -32767

[...]

标准要求类型为 int为整数类型,可以表示 [INT_MIN, INT_MAX] 范围(第 5.2.4.2.1 节)。

然后,6.2.6.2。 (整数类型,也是 C 标准的一部分)开始发挥作用,并将其进一步限制为我们所知道的 二或一的补码:

For signed integer types, the bits of the object representation shall be divided into three groups: value bits, padding bits, and the sign bit. There need not be any padding bits; signed char shall not have any padding bits. There shall be exactly one sign bit. Each bit that is a value bit shall have the same value as the same bit in the object representation of the corresponding unsigned type (if there are M value bits in the signed type and N in the unsigned type, then M ≤ N). If the sign bit is zero, it shall not affect the resulting value. If the sign bit is one, the value shall be modified in one of the following ways:

— the corresponding value with sign bit 0 is negated (sign and magnitude);

— the sign bit has the value −(2M) (two’s complement);

— the sign bit has the value −(2M − 1) (ones’ complement).

第 6.2.6.2 节。将有符号整数类型的值表示与其无符号兄弟的值表示联系起来也非常重要。

这意味着,你要么得到范围 [-(2^n - 1), (2^n - 1)][-2^n, (2^n - 1)] , 其中 n 通常是 15 或 31。

有符号整数类型的操作

现在来说第二件事:对有符号整数类型的操作,导致值不在 [INT_MIN, INT_MAX] 范围内,行为未定义。这是第 5/4 段在 C++ 中明确规定的:

If during the evaluation of an expression, the result is not mathematically defined or not in the range of representable values for its type, the behavior is undefined.

对于 C,6.5/5 提供了一个非常相似的段落:

If an exceptional condition occurs during the evaluation of an expression (that is, if the result is not mathematically defined or not in the range of representable values for its type), the behavior is undefined.

如果 INT_MIN 的值会发生什么?恰好小于 INT_MAX 的负数(例如分别为 -32768 和 32767)?计算 -(INT_MIN)将是未定义的,与 INT_MAX + 1 相同.

因此,我们需要避免计算可能不在 [INT_MIN, INT_MAX] 范围内的值。 .幸运,INT_MAX + INT_MIN始终在该范围内,如 INT_MAX是一个严格的正值,INT_MIN一个严格的负值。因此INT_MIN < INT_MAX + INT_MIN < INT_MAX .

现在我们可以检查是否 INT_MAX + INT_MIN等于、小于或大于 0。

`INT_MAX + INT_MIN`  |  value of -INT_MIN    | value of -INT_MAX 
------------------------------------------------------------------
< 0 | undefined | -INT_MAX
= 0 | INT_MAX = -INT_MIN | -INT_MAX = INT_MIN
> 0 | cannot occur according to 6.2.6.2. of the C standard

因此,确定 INT_MAX 的最小值和 -INT_MIN (在数学意义上),下面的代码就足够了:

if ( INT_MAX + INT_MIN == 0 )
{
return INT_MAX; // or -INT_MIN, it doesn't matter
}
else if ( INT_MAX + INT_MIN < 0 )
{
return INT_MAX; // INT_MAX is smaller, -INT_MIN cannot be represented.
}
else // ( INT_MAX + INT_MIN > 0 )
{
return -INT_MIN; // -INT_MIN is actually smaller than INT_MAX, may not occur in a conforming implementation.
}

或者,为了简化:

return (INT_MAX + INT_MIN <= 0) ? INT_MAX : -INT_MIN;

只有在必要时才会评估三元运算符中的值。因此,-INT_MIN要么未计算(因此不能产生 UB),要么是一个明确定义的值。

或者,如果你想要一个断言:

assert(INT_MAX + INT_MIN <= 0);
return INT_MAX;

或者,如果你想在编译时这样做:

static_assert(INT_MAX + INT_MIN <= 0, "non-conforming implementation");
return INT_MAX;

正确进行整数运算(即,如果正确性很重要)

如果您对安全整数运算感兴趣,请查看我的 implementation of safe integer operations .如果您想查看操作失败和成功的模式(而不是冗长的文本输出),请选择 this demo .

根据架构的不同,可能还有其他选项来保证正确性,比如gcc的选项-ftrapv .

关于c++ - 如何便携地找出 min(INT_MAX, and(INT_MIN))?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29808397/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com