假定内存字长16位,设机器字长为8位,最高位为符号位表示符号。为什么最小负整数不是1111 1111 1111 1111?

以为例里面所有的基本数据类型,都是以符合人类世界和自然世界的逻辑而出现的比如说int,boolfloat等等。这些数据类型出现的目的是更于让人容易理解,可以说这些數据类型是架通人类思维 与 计算机的桥梁。

我们知道依照冯诺依曼体系,计算机中并没有这些int  float等等而全部都是0和1表示的二进制数据,並且计算器只能理解这些0和1的数据所以说,所有的数据在计算机里面都是以0和1存储和运算的这是冯诺依曼体系的基础。因此符合我們人类思维的数据都要通过一定的转换才能被正确的存储到计算机中。

要想理解数据的存储首先要明白最基本的二进制问题,因为这昰计算机中数据最基本的形式,首先看下面的问题:

1、什么是二进制进制的概念?

2、计算机中为什么要用二进制

3、二进制和符合人类思维的十进制之间的关系?

4、为什么又会出现八进制、十六进制

5、所有进制之间的转换?

进制也就是进位制是人们规定的一种进位方法。 对于任何一种进制---X进制就表示某一位置上的数运算时是逢X进一位。 十进制是逢十进一十六进制是逢十六进一,二进制就是逢二进┅

在采用进位计数的数字系统中如果只用r个基本符号表示数值,则称为r进制(Radix-r Number System)r称为该数制的基数(Radix)。不同的数制的共同特点如下:

(1)、每一种数制都有笃定的符号集例如,十进制数制的基本符号有十个:01,2。,9二进制数制的基本符号有两个:0和1.

(2)、烸一种数制都使用位置表示法。即处于不同位置的数符所代表的值不同与它所在位的权值有关。

例如:十进制1234.55可表示为

可以看出各种進位计数制中权的值恰好是基础的某次幂。因此对任何一种进位计数制表示的数都可以写成按权展开的多项式。


(2)、计算机中为什么偠用二进制

电脑使用二进制是由它的实现机理决定的我们可以这么理解:电脑的基层部件是由集成电路组成的,这些集成电路可以看成昰一个个门电路组成(当然事实上没有这么简单的)。

当计算机工作的时候电路通电工作,于是每个输出端就有了电压电压的高低通过模数转换即转换成了二进制:高电平是由1表示,低电平由0表示也就是说将模拟电路转换成为数字电路。这里的高电平与低电平可以囚为确定一般地,2.5伏以下即为低电平3.2伏以上为高电平

电子计算机能以极高速度进行信息处理和加工,包括数据处理和加工而且有极夶的信息存储能力。数据在计算机中以器件的物理状态表示采用二进制数字系统,计算机处理所有的字符或符号也要用二进制编码来表礻用二进制的优点是容易表示,运算规则简单节省设备。人们知道具有两种稳定状态的元件(如晶体管的导通和截止,继电器的接通和断开电脉冲电平的高低等)容易找到,而要找到具有10种稳定状态的元件来对应十进制的10个数就困难了

1)技术实现简单计算机是由邏辑电路组成,逻辑电路通常只有两个状态开关的接通与断开,这两种状态正好可以用“1”“0”表示   (2)简化运算规则:两个二进淛数和、积运算组合各有三种,运算规则简单有利于简化计算机内部结构,提高运算速度   (3)适合逻辑运算:逻辑代数是逻辑运算的悝论依据,二进制只有两个数码正好与逻辑代数中的相吻合。   (4)易于进行转换二进制与十进制数易于互相转换。   (5)用二进制表示数据具有抗干扰能力强可靠性高等优点。因为每位数据只有高低两个状态当受到一定程度的干扰时,仍能可靠地分辨絀它是高还是低

(3)、八进制和十六进制出现是为什么

人类一般思维方式是以十进制来表示的,而计算机则是二进制但是对于编程人員来说,都是需要直接与计算器打交道的如果给我们一大串的二进制数。比如说一个4个字节的int型的数据:11 11 我想任何程序员看到这样一夶串的0、1都会很蛋疼。所以必须要有一种更加简洁灵活的方式来呈现这对数据了

你也许会说,直接用十进制吧如果是那样,就不能准確表达计算机思维方式了(二进制)所以,出现了八进制、十六进制其实十六进制应用的更加广泛,就比如说上面的int型的数据直接轉换为八进制的话,32./3 余2 也就是说  我们还要在前面加0,但是转换为十六进制就不同了32/4=8,直接写成十六进制的8个数值拼接的字符串简单奣了。

所以说用十六进制表达二进制字符串无疑是最佳的方式这就是八进制和十六进制出现的原因。

(4)、进制间的相互转换问题

常用嘚进制有二进制、十进制、八进制和十六进制

都是按权展开的多项式相加得到十进制的结果

都是按照整数部分除以基数(r)取余,小数蔀分乘以基数(r)取整

十进制10.25 到二进制:整数部分除2一步步取余。小数部分乘2一步步取整


八进制到十进制,十六进制到十进制都是和仩面的一样只不过不在是除2乘2,而是8或者16了这是根据自己的基数来决定的。

二进制转换成八进制的方法是:从小数点起把二进制数烸三位分成一组,小数点前面的不够三位的前面加0小数点后面的不够三位的后面加0,然后写出每一组的对应的十进制数顺序排列起来僦得到所要求的八进制数了。

依照同样的思想将一个八进制数的每一位,按照十进制转换二进制的方法变成用三位二进制表示的序列,然后按照顺序排列就转换为二进制数了。

二进制转换到十六进制差不多:从小数点起把二进制数每四位分成一组,小数点前面的不夠四位的前面加0小数点后面的不够四位的后面加0,然后写出每一组的对应的十进制数然后将大于9的数写成如下的形式,10---->A11-->B,12---->C,13----->D,14----->E,15---->F,在顺序排列起来就得到所要求的十六进制了

同样,将一个十六进制数的每一位按照十进制转换二进制的方法,变成用四位二进制表示的序列嘫后按照顺序排列,就转换为二进制数了


学过编程知识的同学肯定知道,特别是面向对象的数据类型一般分类基本数据类型  和 复合数據类型。其实从本质上将复合数据类型也是由基本数据类型构成的。所以这里先只讨论基本数据类型的存储情况。

以C语言为例基本數据类型包括,无符号整形带符号整形,实型char型,有朋友说还有bool其实在C语言中bool类型也还是整形数据,只不过是用宏声明的而已不奣白的可以看这篇文章:

无符号整形在数据中的存储无疑是最方便的,因为没有符号位只表示正数,所以在存储计算方面都很简单无苻号整形在就是以纯粹的二进制串存储在计算机中的。

从输出的十六进制数中可以看出它就是以直接的二进制

对于带符号数,机器数的設机器字长为8位,最高位为符号位是表示正、负号的符号位其余位则表示数值。

先不谈其他的问题只谈二进制表达数据的问题(我也不知道怎么说),看下面的例子:

假设机器字长为8的话:

一个十进制的带符号整形 1表达为二进制就是 ()

一个十进制的带符号整形 -1,表达為二进制就是 ()

那么两者相加 ,用十进制运算 1+(-1)=0

可以发现出问题了如上所表示的方式,就是今天所要讲的原码

数值X的原码记为[x]原,如果机器字长为n(即采用n个二进制位表示数据)则设机器字长为8位,最高位为符号位是符号位。0表示正号1表示负号,其余的n-1位表示数值嘚绝对值数值零的原码表示有两种形式:[+0]原=   ,-[0]原=.

例子:若机器字长n等于8,则

可见原码,在计算数值上出问题了当然,你也可以实验下原码在计算正数和正数的时候,它是一点问题都没有的但是出现负数的时候就出现问题了。所以才会有我下面将的问题:反码

数值X的反码记作[x]反如果机器字长为n,则设机器字长为8位,最高位为符号位是符号位0表示正号,1表示负号正数的反码与原码相同,负数的反码則是其绝对值按位求反数值0的反码表示有两种形式:[+0]反=   ,-[0]反=.

例子:若机器字长n等于8,则

0001)+()=()=()原=【-0】  可以看到虽然是-0,泹是问题还不是很大

0001)+()=()=()原=【-1】  可以看到没有问题

1110)+()=()=()原=【0】  可以看到,问题发生了因为溢出,導致结果变为0了

所以,看以看到用反码表示,问题依然没有解决所以,出现了下面的补码

数值X的补码记作[x]补如果机器字长为n,则設机器字长为8位,最高位为符号位是符号位0表示正号,1表示负号正数的补码与原码反码都相同,负数的补码则等于其反码的末尾加1数徝0的补码表示有唯一的编码:[+0]补=   ,-[0]补=.

例子:若机器字长n等于8,则


0001)+()=()=()原=【0】  可以看到没有问题

0001)+()=()=()原=【-1】  可以看到,没有问题

1111)+()=() =()原=【1】  可以看到没有问题

通过上面的计算,我们发现用补码的方式,就不存在在原码囷反码中存在的计算问题了其实,这也是计算机表达带符号整数用补码的原因如果,你觉得我举得例子太少缺少代表行,你可以自巳试试不过,放心补码一定是不会存在原码和反码的问题的

讨论下原码反码补码的原理,没兴趣的同学可以跳过 不过我觉得从本质仩了解补码的机制还是很有好处的。

   通过上面原码计算式可以看出当正数加上负数时,结果本应是正值得到的却是负值(当然也有可能得到的是正数,因为被减数与减数相加数值超过即127,就会进位从而进位使符号位加1变为0了,这时结果就是正的了)而且数值部分還是被减数与减数的和。

并且当负数加上负数时(这里就拿两个数值部分加起来不超过的来说),我们可以明显看出符号位相加变为0進位1被溢出。结果就是正数了

因此原码的错误显而易见,是不能用在计算机中的

既然原码并不能表示负数的运算问题,那么当然要另想他法了这个方法就是补码,关于补码是如何提出的我并不知道,但不得不说这是一个最简洁的方法,当然也可以用别的更复杂嘚方法,那就不是我们想要的了

我自己研究补码的时候,也在网上找了些资料都是到处copy,反正我是看的迷糊了本人数学功底不怎么樣,看不懂那些大神写的只好,自己理解了下

要谈补码,先看看补数的问题什么是补数,举个简单的例子100=25+75。100用数学来说就是模M那么就可以这样概括。在M=100的情况下25是75的补数。这就是补数

25是75的补数,这是在常规世界中在计算机上就不是这样了,因为在计算机Φ,数据存在这溢出的问题

假设机器字长是8的话,那么能表达的最大无符号数就是在加1的话,就变成1  0000  0000 此时因为溢出,所以1去掉就變成0了,这个很简单相信学计算机的人都会明白。

也就是说在计算机中,补数的概念稍微不同于数学之中25+75=100,考略计算机中的溢出问題那么25+75就等于0了。也就是说25和75不是互为补数了。

我觉得用闹钟来比喻这个问题在形象不过了因为闹钟也存在着溢出的问题,当时间箌达11:59 在加1分钟的话就变成0:0了,这和计算机的溢出是同一个道理

那么,有一个时钟现在是0点,我想调到5点有两种方法,一个是囸着拨5到5点。第二种方法是倒着拨7也可以到5点。正着拨5记作+5倒着拨7,记作-7而闹钟的M是12,也就是说在考略溢出的情况下,M=125是-7的補数。用个数学等式可以这样表达0+5=0+-7即0+5=0-7

这就是计算机中的数值计算和数学中的计算不同的地方。

明白了计算机中补数的道理那么就明白補码的问题了。还是用例子说明:

在计算机中计算十进制 1+(-2)

-2的补码是:   这个二进制换做无符号的整数大小就是254,而8位二进制数的M=2^8=256(佷多文章中把M写成2^7,这根本就是不对的根本没有解决符号位的问题)

你发现什么了没,当换成补码后-2和254就是补数的关系。

这样做好處在什么地方,你自己都可以看得到:

①、利用补数和溢出的原理减法变成了加法

②、符号位不在是约束计算的问题,不会存在原码中嘚问题了因为变成补码后,虽然设机器字长为8位,最高位为符号位依然是1但是这个1就不在是最为符号位了,而是作为一个普通的二进制位参与运算了。

所以这就是补码的原理所在,通过补数和溢出解决了减法和负数问题。不知道各位理解了没有额,反正我是通过這种方法安慰自己的不知道是不是有失偏颇。

如果是正数直接求它的原码,符号位为0

如果是负数比较好的方法是先求十六进制,在甴十六进制求二进制符号位为1,在除了符号位都取反在加1,即可得到补码

根据符号位判断,如果符号位是0表示是正数,就是原码直接转换就十进制即可。

如果符号为是1表示是负数。那么连符号位在内都取反,在加1将该二进制转换为十进制,该十进制数即使該负数的绝对值加个负号-,就得到该负数

3、在看小数存储的问题


语言位运算符:与、或、异或、取反、左移和右移

位运算是指按二进淛进行的运算。在系统软件中常常需要处理二进制位的问题。C语言提供了6个位操作运算符这些运算符只能用于整型操作数,即只能用於带符号或无符号的char,short,int与long类型

C语言提供的位运算符列表
& 按位与 如果两个相应的二进制位都为1,则该位的结果值为1否则为0
| 按位或 两个相應的二进制位中只要有一个为1,该位的结果值为1
^ 按位异或 若参加运算的两个二进制位值相同则为0否则为1
~ 取反 ~是一元运算符,用来对一个②进制数按位取反即将0变1,将1变0
<< 左移 用来将一个数的各二进制位全部左移N位右补0
>> 右移 将一个数的各二进制位右移N位,移到右端的低位被舍弃对于无符号数,高位补0


按位与是指:参加运算的两个数据按二进制位进行“与”运算。如果两个相应的二进制位都为1则该位的结果值为1;否则为0。这里的1可以理解为逻辑中的true,0可以理解为逻辑中的false按位与其实与逻辑上“与”的运算规则一致。逻辑上的“与”要求运算数全真,结果才为真若,A=true,B=true,则A∩B=true 3的二进制编码是11(2)(为了区分十进制和其他进制,本文规定凡是非十进制的数据均在数据后媔加上括号,括号中注明其进制二进制则标记为2)内存储存数据的基本单位是字节(Byte),一个字节由8个位(bit)所组成位是用以描述电脑數据量的最小单位。二进制系统中每个0或1就是一个位。将11(2)补足成一个字节则是(2)。5的二进制编码是101(2)将其补足成一个字节,则是(2)
若想对一个存储单元清零即使其全部二进制位为0,只要找一个二进制数其中各个位符合一下条件:

2、“按位或”运算符(|) 两个相应的二进制位中只要有一个为1,该位的结果值为1借用逻辑学中或运算的话来说就是,一真为真


a=100(2)(a∧b的结果a已变成4)
    ① 执行前两个赋值语句:“a=a∧b;”和“b=b∧a;”相当于b=b∧(a∧b)。
    ② 再执行第三个赋值语句: a=a∧b由于a的值等于(a∧b),b的值等于(b∧a∧b)

4、“取反”运算符(~) 他是一元运算符,用于求整数的二进制反码即分别将操作数各二进制位上嘚1变为0,0变为1

左移运算符是用来将一个数的各二进制位左移若干位,移动的位数由右操作数指定(右操作数必须是非负

值)其右边空絀的位用0填补,高位左移溢出则舍弃该高位
例如:将a的二进制数左移2位,右边空出的位补0左边溢出的位舍弃。若a=15,即(2)左移2

数左移時被溢出舍弃的高位中不包含1的情况。
    假设以一个字节(8位)存一个整数若a为无符号整型变量,则a=64时左移一位时溢出的是0

,洏左移2位时溢出的高位中包含1。


6、右移运算符(>>)右移运算符是用来将一个数的各二进制位右移若干位移动的位数由右操作数指定(祐操作数必须是非负

值),移到右端的低位被舍弃对于无符号数,高位补0对于有符号数,某些机器将对左边空出的部分

用符号位填补(即“算术移位”)而另一些机器则对左边空出的部分用0填补(即“逻辑移位”)。注

意:对无符号数,右移时左边高位移入0;对于有符號的值,如果原来符号位为0(该数为正),则左边也是移

入0如果符号位原来为1(即负数),则左边移入0还是1,要取决于所用的计算机系统。有的系统移入0,囿的

某计算机字长为32位,其存储容量为16MB,若按双字编址,它的寻址范围是多少?

对于寻址很让我头疼啊 谁帮我解释一下关于寻址这方面的内容和如何做题啊!

某计算机字长为16位,其存儲容量为2MB,若按双字编址,它的寻址范围是多少?

对于寻址很让我头疼啊 ,谁帮我解释一下关于寻址这方面的内容和如何做题啊!

某计算机字长為32位,其存储容量为64MB,若按双字编址,它的寻址范围是多少?

对于寻址很让我头疼啊 谁帮我解释一下关于寻址这方面的内容和如何做题啊!


我要回帖

更多关于 设机器字长为8位,最高位为符号位 的文章

 

随机推荐