C++中short, int, long, long long以及对应unsigned的范围
在 C++ 中,short
, int
, long
类型的大小由编译器和目标平台共同决定。
1 |
|
例如在64位Ubuntu中使用g++编译并运行输出以下内容:
1 | 2 |
在64位windows11中使用g++编译并运行输出以下内容:
1 | 2 |
区别在于long,在ubuntu下它是8字节,在windows下它和int一样是4字节。
下面基于Ubuntu来计算short, int, long的取值范围。
现代的CPU都采用补码来表示有符号整数,关于补码的介绍参考:原码 反码 补码的原理
short
short 和 unsigned short都只占16bit,区别是short为有符号类型,unsigned short为无符号类型。有符号数在计算机内部用补码表示,即最高位表示符号位,0为正数,1为负数。
对于有符号数,除了最高位为符号位,还可以使用15位来表示数字
能表示的最小数字(补码)是:1000 0000 0000 0000,即 -32768
其能表示的最大数字(补码)是:0111 1111 1111 1111 ,即32767
所以 shor的范围为:[-$2^{15}$ ,$2^{15}-1$ ]即 [-32768, 32767]
unsigned short没有符号,所以可以用16bit来表示数据。最小值是0000 0000 0000 0000
即0,最大值是1111 1111 1111 1111
即65535
所以 short 的范围为:[0, $2^{16}-1$]即[0,65535]
为了方便表示二进制数,下面统一用十六进制数,每4位二进制数表示1位十六进制数。、
例如 0111 1111 1111 1111
用十六进制表示为:7FFF
int
int 和 unsigned int都占32位,前者为有符号类型,后者为无符号类型。在计算机中有符号数都用补码表示。
int 能表示的最小数字(十六进制补码)为:8000 0000,即-2147483648
int 能表示的最大数字(十六进制补码)为:7FFF FFFF,即2147483647
所以int的范围为:[$-2^{31}, 2^{31}-1$]即[-2147483648, 2147483647]
同理,unsigned int没有符号位。最小值(十六进制):0000 0000
即0 ,最大值(十六进制):FFFF FFFF
即4,294,967,295
所以 unsigned int 的范围为:[0, $2^{32}-1$]即[0,4,294,967,295 ]
long
long 和 unsigned long都占64位,前者为有符号类型,后者为无符号类型。在计算机中有符号数都用补码表示。
long 能表示的最小数字(十六进制补码)为:8000 0000 0000 0000
即-9,223,372,036,854,775,808 读作负的九百二十二京三千三百七十二兆三百六十八亿五千四百七十七万五千八百零八
long 能表示的最大数字(十六进制补码)为:7FFF FFFF FFFF FFFF
,即9,223,372,036,854,775,807
所以 long的范围为:[$-2^{63}, 2^{63}-1$]
同理,unsigned long没有符号位,最小值(十六进制):0000 0000 0000 00000
,最大值(十六进制):FFFF FFFF FFFF FFFF
即18,446,744,073,709,551,615
读作 一千八百四十四京…
所以unsigned long的范围为:[0,$2^{64}-1$ ]
long long
long long 的大小是跨平台固定的,不管在Linux 还是 Windows下它都是64位。范围参考上述的long 的范围。
公式
对于 n 位二进制数。
有符号数的范围为:[$-2^{n-1}$, $2^{n-1}-1$]
无符号数的范围为:[0, $2^n-1$]