整数与二进制相关的tricks。

整数

整数范围&数量级

注意一点,32位整数的数量级是40亿,也就是10^9,如果数据范围是10^9级别,则需要考虑是否要用64位整数来表示。

符号位与补码

C++支持无符号数和有符号数,重点关注有符号数的表示。

对于有符号数,最高位表示符号位,符号位为0,表示这个数是正数,否则为负数。对于负数的表示,C++使用补码来表示负数,补码等于原码除符号位外全部取反再加1。

以8位有符号数-1和-128为例,其原码,反码,补码如下:

-1:

原码1000 0001
反码1111 1110
补码1111 1111

-128:

原码
反码
补码1000 0000

一个数字从0开始不断加1,其表示的有符号数变化过程为:

  • 0
  • 正数不断增大
  • 最大正数(符号位为0,其他全1)
  • 最小负数(符号位为1,其余全0)
  • 负数不断增大
  • -1。

以上过程可用于判断正数累加是否溢出,即一个正数在累加的过程中突然从正数变成了负数,则表示这个数已经溢出了。

C++整数相关的常量

在头文件<limits.h>和<float.h>(C++对应为<climits>和<cfloat>)中有整数和浮点数相关的常量宏定义,可能用到的有以下几个:

描述可能值
SHRT_MINshort int类型的最小值-32768
SHRT_MAXshort int类型的最大值32767
USHRT_MAXunsigned short int类型的最大值65535
INT_MINint类型的最小值-2^31
INT_MAXint类型的最大值2^31 - 1
UINT_MAXunsigned int类型的最大值2^32 - 1
LONG_MINlong int类型最小值
LONG_MAXlong int类型最大值
ULONG_MAXunsigned long int类型最大值
LLONG_MINlong long int类型最小值 -2^63
LLONG_MAXlong long int类型最大值2^63 - 1
ULLONG_MAXunsigned long long int类型最大值2^64 - 1

FLT_MIN

DBL_MIN

LDBL_MIN

各浮点类型最小值

1.17549e-38

2.22507e-308

3.3621e-4932

FLT_MAX

DBL_MAX

LDBL_MAX

各浮点类型最大值

3.40282e+38

1.79769e+308

1.18973e+4932

这里注意一点,对于char类型,标准并没有规定它是signed还是unsigned类型,所以没法确定CHAR_MIN的值。如果编译器实现上把char当成有符号类型,则CHAR_MIN的值应该是-128,否则,如果编译器认为char是无符号类型,那么CHAR_MIN的值应该是0。以下是在Ubuntu20.04上的测试结果:

SCHAR_MIN:-128
SCHAR_MAX:127
UCHAR_MAX:255
CHAR_MIN:-128
CHAR_MAX:127

可以看出,这里编译器把char当成有符号来对待。

整数相关的tricks

zigzag算法

二进制


  • 无标签