计算机眼里的数字

一、数字系统
我们目前使用的大多数数字系统是基于位置的,即对位置敏感的。在数字中符号所占据的位置决定了其表示的值。比如十进制22,两个符号“2”所代表的含义是不同的,左边表示两个十,右边表示两个一。每个数字系统由两个基本部分组成,符号集和基数。符号集就是用来表示每个具体数字的所有符号,比如阿拉伯数字的十个符号0~9;基数就是这个符号集内所有元素的个数,基数是不外显的,在指定使用哪个进制系统的时候就已经暗含了。符号集可以重用及扩充,如我们的二进制直接取了十进制符号集的一个子集:{0,1},而十六进制不过就是在十进制符号集的基础上增加了{A,B,C,D,E,F}来表示10,11,12,13,14,15罢了。
每个位置的符号所代表的实际大小等于该符号本身的大小乘以基数的某个杨幂,哦不,是方幂。以小数点为界,左边幂的大小从右往左依次为0、1、2……而右边幂的大小从左往右依次为-1、-2、-3…… 如十进制的425 = 4 × 100 + 2 × 10 + 5 × 1,二进制的11.11 = 1 × 2 + 1 × 1 + 1 × 1/2 + 1 × 1/4 = 3.75(十进制)。
在书写数字的时候,是有正负之分的,有明确的可以作为标识正负的符号,即“+”、“-”,而且“+”一般是被忽略的,也就是如果没有符号,则默认为正。另外,为了便于区分书面的数字进制形式,八进制要以数字0为开头,十六进制以0x开头,其他的数字默认为十进制。


二、位与字节
我们知道,计算机用二进制表示一切信息,而二进制在内存中的实现依靠的是电容等电子器件,当电容充满电时状态为1,没有电时状态为0。两个这样的电子器件组合在一起就有00、01、10、11四种状态,于是就可以表示0、1、2、3四个数字,当然也可以表示其他四个信号或信息,如四种不同的颜色。每个这样的电子器件表示为一个位,位就是计算机表示信息的最小单位。每个位的值是0或1,那么n个位组合起来能表示的信息量就是2的n此方。当n = 8时,称为一个字节。一个字节显然有2的8此方即256种状态,可以表示256种信息,于是我们可以用它来表示0~255这256个非负数。一般来说,我们以字节为单位承载信息,而不是以最小的单位——位,就像军队调动的时候以排或班为单位而不是每个人一样。这样可能会有些浪费,比如我要表示5这个数,其实只要表示成101就好了,三位就已足够,但是用字节来承载的话,就会写成00000101,前面5位会被置0。 


三、无符号数与有符号数

首先要理解这两个概念是如何产生的。在一些情况下,我们只需要非负数就可以完成工作,比如数数、计时,这时候负数完全派不上用场,符号对于我们是多余的。但是在另一些场合,比如负债表,负数就很有必要。

但无论是哪种数,都是用二进制表示的。以一个字节为例,在没有引入负数之前,字节的每个位都解释为一个数;而为了表示负数,字节的最高位必须解释为符号(0为负号1为正号)。所以,同一串数字,如1111 1111,虽然在CPU那里没什么区别,但是对人类来讲却有两种不同的解释方式——关键在于最高位解读成符号还是数字,当解读成符号时,它就是个无符号数;而解读成符号,就是有符号数。

实际上,不同的编程语言对于有符号数和无符号数的规定是不同的:比如C语言以及C++允许定义无符号数;而Java语言规定所有数字都必须是有符号数。由此我们可以推知,对二进制数字的解读发生在编译器层面,而CPU对所有二进制代码都是一视同仁的。


定义了符号位之后,是不是剩下的事情就顺理成章了呢?比如把1111 1111解读成有符号数,那么它对应的十进制数字就是-7?答案是未必。因为负数也有不同的表示方式,解读成-7是所谓的原码表示法,另外还有反码和补码表示法。实际上,几乎所有的计算机都采用补码表示法来解读有符号数。在补码表示法中,1111 1111解读为-1,其公式如下:

符号位乘以对应的方幂并取反,剩余的数字位按照无符号数解读,二者再求和。

1111 1111 = -1 × 2 ^ 7 + 111 1111 = -128 + 127 = -1


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值