在没有 <limits.h> 或 <values.h> 的系统上查找SHRT_MAX

Finding SHRT_MAX on systems without <limits.h> or <values.h>

本文关键字:lt gt 查找 SHRT MAX 系统 limits values      更新时间:2023-10-16

我正在读托尼·汉森(Tony L Hansen(的《C++答案书》。它在某处说,SHRT_MAX的值(空头的最大值(可以推导出如下:

const CHAR_BIT=           8;
#define BITS(type)       (CHAR_BIT*(int)sizeof(type))
#define HIBIT(type)      ((type)(1<< (BITS(type)-1)))
#define TYPE_MAX(type)   ((type)~HIBIT(type));
const SHRT_MAX=          TYPE_MAX(short);

有人可以用简单的话解释上述 5 行发生了什么吗?

const CHAR_BIT=           8;

假设在此处(和下面(添加intCHAR_BITchar中的位数。此处假定其值而不进行检查。

#define BITS(type)       (CHAR_BIT*(int)sizeof(type))

BITS(type)type位数。如果sizeof(short) == 2,则BITS(short)8*2

请注意,C++ 不保证除char之外的整数类型中的所有位都对该值有贡献,但以下仍将假定这一点。

#define HIBIT(type)      ((type)(1<< (BITS(type)-1)))

如果BITS(short) == 16,则HIBIT(short)((short)(1<<15))。这依赖于实现,但假定已设置符号位,并且所有值位为零。

#define TYPE_MAX(type)   ((type)~HIBIT(type));

如果HIBIT(short)(short)32768,则TYPE_MAX(short)(short)~(short)32768。这假定已清除符号位,并设置了所有值位。

const SHRT_MAX=          TYPE_MAX(short);

如果满足所有假设,如果这确实设置了所有值位,但没有设置符号位,那么这是short中可表示的最高值。

当您

知道以下情况时,可以在现代C++中更可靠地获得最大值:

  • 无符号类型的最大值很容易获得
  • 有符号类型的最大值肯定
  • 等于相应无符号类型的最大值,或者该值右移,直到它在有符号类型的范围内
  • 超出范围的值转换为有符号类型没有未定义的行为,而是在有符号类型的范围内提供实现定义的值:
template <typename S, typename U>
constexpr S get_max_value(U u) {
S s = u;
while (s < 0 || s != u)
s = u >>= 1;
return u;
}
constexpr unsigned short USHRT_MAX = -1;
constexpr short SHRT_MAX = get_max_value<short>(USHRT_MAX);

稍微重新格式化一下:

const CHAR_BIT = 8;

C++中的代码无效,看起来像旧的 C 代码。让我们假设const int的意思。

#define BITS(type)       (CHAR_BIT * (int)sizeof(type))

返回类型假定为 8 位字节的位数,因为sizeof返回type的对象表示形式的字节数。

#define HIBIT(type)      ((type) (1 << (BITS(type) - 1)))

假设type是 2 补码中的有符号整数,这将返回具有最高位集的该类型的整数。例如,对于 8 位整数,您将获得1 << (8 - 1) == 1 << 7 == 0b10000000 == -1.

#define TYPE_MAX(type)   ((type) ~HIBIT(type));

前一个事物的按位not,即翻转每个位。按照与之前相同的示例,您将获得~0b10000000 == 0b01111111 == 127

const SHRT_MAX = TYPE_MAX(short);

在 C 和 C++ 中再次无效。在C++中由于缺少int,在C中由于CHAR_BIT不是一个常量表达式。让我们假设const int.使用前面的代码获取short类型的最大值。

一次一行:

const CHAR_BIT=           8;

CHAR_BIT声明并初始化为const int类型的变量 值8.这是有效的,因为int是默认类型(错误:请参阅下面的评论(,尽管它是 指定类型的更好做法。

#define BITS(type)       (CHAR_BIT* (int)sizeof(type))

预处理器宏,将类型转换为其中的位数 类型。(星号不是做任何指针,而是用于 乘法。如果作者之前放了一个空格会更清楚 它。

#define HIBIT(type)      ((type)(1<< (BITS(type)-1)))

宏,将类型转换为具有最高位的该类型的数字 设置为 1 位,所有其他位为零。

#define TYPE_MAX(type)   ((type)~HIBIT(type));

宏,反相HIBIT,因此最高位为零,所有其他位均为零 一。这将是type的最大值,如果它是有符号类型并且 机器使用二的补码。分号不应该在那里,但是 它将在此代码中工作。

const SHRT_MAX=          TYPE_MAX(short);

使用上述宏计算short的最大值。