在没有 <limits.h> 或 <values.h> 的系统上查找SHRT_MAX
Finding SHRT_MAX on systems without <limits.h> or <values.h>
我正在读托尼·汉森(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;
假设在此处(和下面(添加int
:CHAR_BIT
是char
中的位数。此处假定其值而不进行检查。
#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
的最大值。
- 请解释这句话(cout<<1+int((a<b)^((b-a)&1) )<<endl
- 呼叫运营商<<临时
- 如何防止clang格式在流运算符调用之间添加换行符<<
- <<操作员在下面的行中工作
- EASTL矢量<向量<int>>连续的
- C - 创建矢量&lt; vector&lt; double&gt;&gt;矩阵具有分配而不是inizializ
- 为什么将此对向量&lt; map&lt; int,int&gt;&gt;中的地图进行更新.失败
- C :对矢量进行排序&lt; struct&gt;(结构有2个整数)基于结构的整数之一
- 明确的专业化“ CheckIntmap&lt;&gt;”实例化
- 什么是模板&lt;&gt;inline bla bla
- 编辑C Qlist&lt; object*&gt; gt;QML代码和一些QML警告中的模型
- eigen :: llt&lt;eigen :: matrixxd&gt;具有不完整的类型
- 错误,包括&lt; ctype&gt;在原子上使用C 11
- std::vector<;uint8_t>;当C++11/14启用时,手动复制而不是调用memcpy
- 如何加入向量&lt; int&gt;到C 中的单个INT
- 是std :: set&lt; std :: future&gt;不可能存在
- 是numeric_limits&lt; int&gt; :: is_modulo从逻辑上矛盾
- opencv 2.4.7在iOS错误背景_segm.hpp #include&lt; list&gt;未找到
- 在修改列表后,std :: list&lt; t&gt; :: end()的值是否会更改
- ///<评论></评论>在Visual Studio中