C++中short, int, long, long long以及对应unsigned的范围

在 C++ 中,shortintlong类型的大小由​​编译器和目标平台共同决定

1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>

using namespace std;

int main() {
cout << sizeof(short) << endl;
cout << sizeof(int) << endl;
cout << sizeof(long) << endl;
cout << sizeof(long long) << endl;

return 0;
}

例如在64位Ubuntu中使用g++编译并运行输出以下内容:

1
2
3
4
2
4
8
8

在64位windows11中使用g++编译并运行输出以下内容:

1
2
3
4
2
4
4
8

区别在于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 FFFF4,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 FFFF18,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$]