3.1.3 三位二进制的数值范围
提示
如果你暂时无法理解整型取值范围的原理分析,则可以先记住 sizeof 的使用以及各种整型变量的取值范围的结论。不理解整型取值范围的原理不会影响你对C语言的使用。你可以直接跳过这些章节,到3.1.5节继续学习。
在C语言中,char、short、int、long和long long分别占用了1字节、2字节、4字节、4字节和8字节。每个字节由8个晶体管组成,每个晶体管状态我们称之为位。因此,char、short、int、long和long long分别占用了8、16、32、32和64位。
为了方便理解,我们暂时将位数简化为3,然后分析3位的组合,看它能表示多大范围的数值。你只要能够理解3位可以表示的数值范围,那么扩展到8、16、32、64位也是同样的原理,也就能够理解它们。三位二进制数如图3.3所示。
三位二进制组成的数据类型可以表达2的3次方,即8个数值。如果从0开始,那么可以表达0~7的数值范围。因此,我们可以得出以下结论。
如果不考虑负数,那么整型数据类型可以表达的数值范围是:假设位数为n,则数值范围为从0开始,到2的n次方减1。
但是,在考虑负数的情况下,我们需要用一个位来作为符号位,表示这个数据是正数还是负数。通常我们用0表示正数,用1表示负数。在C语言标准中,符号位存在于二进制的最高位。下面我们用3位二进制来演示这种情况。三位二进制带负数如图3.4所示。
图3.3 三位二进制数
图3.4 三位二进制带负数
加上符号位之后,现在取值变为-4~3了。图3.4中用方框展示了最高位,最高位为1的表示负数。你可能会觉得有点奇怪,为什么3的二进制是011,而-3却是101呢?如果只是简单地加一个符号位,为什么不将-3写成111呢?
想要回答这个问题,我们看看图3.5中所示的3与-3相加的运算结果。这里需要注意的是,该图中的运算是二进制的运算,因此运算方式是逢二进一的。
你会惊奇地发现,用101表示-3与用011表示的3相加的结果为1000。但由于仅有3位二进制保存数据,最高位1被丢弃了,结果为000,居然得到了正确的结果0。为什么会这样呢?
图3.5 3与-3补码相加