为什么所有数据类型的大小都是2的幂次方?
我们来看两个例子:
short int 16
char 8
为什么它们不像以下这样呢?
short int 12
为什么所有数据类型的大小都是2的幂次方?
我们来看两个例子:
short int 16
char 8
short int 12
那只是一些实现细节,并不总是这样。一些奇特的架构拥有非二的数据类型。例如,36位字长曾经很常见。
如今,二的幂次方之所以几乎普遍,是因为它通常简化了内部硬件实现。举个假设的例子(我不从事硬件设计,所以必须承认这主要是猜测),一个操作码表示其参数大小的部分可以被存储为该参数字节数的二的幂次方索引,因此两个比特就足以表达参数是8、16、32或64位中的哪一个,而将其转换为适当的锁存信号所需的电路将非常简单。
他们是2的幂次方,因为它们是8的倍数,这(稍微简化一下)来自于内存中通常的原子分配单元是字节,而(修正:通常情况下是由8个位组成的)。
更大的数据大小通过一次取多个字节来创建。 所以你可以有8、16、24、32...等数据大小。
然后,出于提高内存访问速度的考虑,只使用2的幂次方作为最小尺寸(8)的乘数,因此你得到了这些数据大小:
8 => 8 * 2^0 bits => char
16 => 8 * 2^1 bits => short int
32 => 8 * 2^2 bits => int
64 => 8 * 2^3 bits => long long int
8位是字节最常见的大小(但不是唯一的大小,9位字节和其他字节大小的例子也很容易找到)。更大的数据类型几乎总是字节大小的倍数,因此它们通常在具有8位字节的系统上为16、32、64、128位,但不总是2的幂,例如DSP常用24位,并且存在80位和96位浮点类型。
struct mystruct
{
short int twelveBitInt : 12;
short int threeBitInt : 3;
short int bitFlag : 1;
};
这在嵌入式/低级环境中非常方便 - 但请记住,结构的总大小仍将被打包到完整大小。
它们不一定是这样的。在某些机器和编译器上,sizeof(long double) == 12
(96位)。
并非所有数据类型都需要使用2的幂作为位数来表示。例如,long double 使用80位(尽管其实现取决于分配多少位)。
使用2的幂的一个优点是,较大的数据类型可以表示为较小的数据类型。例如,4个字符(每个字符8位)可以组成一个int(32位)。事实上,一些编译器曾经使用两个32位数字来模拟64位数字。
有一些情况下,整数类型必须是2的幂次方。如果<stdint.h>
中存在精确宽度类型,例如int16_t
或uint32_t
,它们的宽度必须恰好为该大小,没有填充。声明遵循IEEE标准的浮点数运算强制float
和double
成为2的幂次方(尽管long double
通常不是)。此外,现在标准库或内置于C++中还有char16_t
和char32_t
等类型,定义为精确宽度类型。对于支持UTF-8的要求实际上意味着char
和unsigned char
必须恰好为8位宽。
实际上,许多旧代码已经无法在不支持8、16、32和64位宽度类型的任何计算机上运行。例如,任何读取或写入ASCII或尝试连接到网络的程序都将崩溃。
一些具有历史意义的大型机和小型计算机的本地字长是3的倍数,而不是2的幂,特别是DEC PDP-6、PDP-8和PDP-10。
这是八进制在计算中曾经流行的主要原因:由于每个八进制数字代表三个比特,因此9、12、18或36位模式可以更整洁地用八进制数字表示,而不是十进制或十六进制。例如,当使用基于64位的六位字符打包而不是八位时,每个打包字符占用两个八进制数字。
这些体系结构最明显的遗产是,在C语言中,默认情况下,诸如'\123'
之类的字符转义被解释为八进制而不是十进制,并且Unix文件权限/掩码表示为三个或四个八进制数字。
CHAR_BIT==9
,而int
为36位。 - dreamlax