精华内容
下载资源
问答
  • 1. 信息在计算机系统中的表示 我们知道,信息在计算机系统中是以二进制的方式进行传送,存储的。那么信息在计算机系统中是如何表示的呢?在这里可分为数值信息和非数值信息两个方面进行讨论。 数据信息分类示意图...

    1. 信息在计算机系统中的表示

    我们知道,信息在计算机系统中是以二进制的方式进行传送,存储的。那么信息在计算机系统中是如何表示的呢?在这里可分为数值信息和非数值信息两个方面进行讨论。

    数据信息分类示意图

     

    1.1 数值信息在计算机系统中的表示

    数值信息是有正负之分的,因此,在计算机中存储数值信息必须要有表示符号的方法。由于计算机内是采用二进制编码表示,因此,在一般情况下,我们用“0”表示正号,“1”表示符号,符号位数放在数的最高位。

    例如,比如我们有十进制数A= +91,B= -91,8位二进制数A=(+1011011),B=(-1011011),A和B可以在计算机中表示为:

    A和B在计算机中的表示
    A:0(符号位)1011011
    B:1(符号位)1011011

    可以看出,最左边一位代表符号位,它们连同数字本身一起作为一个数。数值信息在计算机内采用符号和数字化处理后,便可以识别和表示带符号的数值信息了,而根据对负数不同的编码方式,又可分为原码、反码、补码三种方式。

    1.1.1 原码

    同上所述,直接将符号位数字化为0或1,不再进行其他处理,然后将数的绝对值与符号一起编码,即所谓“符号—绝对值表示”的编码,我们称之为原码(未经过其他处理故我们称之为"原")。

    其实上面我们已经说了如何用原码表示一个带符号的整数,如上所述,如果用一个字节(8位)放一个整数,其原码表示如下:

    A= +91= +0101011   [A原] = 00101011 ;

    B= -91=  -0101011   [B原] = 10101011 ;

    这里的“原”就是机器数,就是存放在计算机里的实际二进制数字,前面带符号的二进制数我们称之为机器数相对应的真值

    那我们采用原码有什么好处呢?首先就是编码很简单,我们只需要将真值里面的符号数转为0或1就可以变为机器数,机器数和真值转换很方便,一看就懂。

    那采用原码表示有什么缺陷吗?还真有,第一个就是零的表示不唯一,我们知道,0是没有符号的,+0和-0都是一样的,没有区别的,那么问题来了,我们如何表示0呢?

    [+0] = 00000000                                 [-0]=100000000

    以上两个表示方式都对,所以[0]的表示就有了二义性,这就给机器判零带来了麻烦。

    第二个缺陷就是直接用原码进行四则运算时,符号位需要单独处理,且运算规则复杂,例如进行一个加法运算,若两数同号,那么要取两数相同的符号作为最终符号;若两数异号,则要用大数减去小树,再把大数的符号作为最终的符号。虽然我们看起来很好理解,但实际上这种操作对计算机来说是及其麻烦的,因此,人们找到了更好的编码方式来代替,那就是补码表示法。

    1.1.2 补码

    要说到补码,必须先介绍下什么是反码。反码是基于原码基础上按位取反的,但是需要注意的是符号位是不变的。也就是说:

    原码和补码
    A:+0101011
    A原:0101101

    1

    A反:0(不变)010010

    0

     和原码一样,反码对0的表示也不唯一。

    介绍完反码,我们就可以引出补码的概念,补码在原理上其实是运用了“模数”的概念,在模数系统中有这么一个概念:

    若一个数减去另一个数,或者说一个数加上一个负数,等价于第一个数加上第二个数的补数。

    比如,我们取模数为12,那么:

    8 + (-2) = 8 +10 (mod12) = 6

    为什么这么做呢?这样我们就把加上一个“负数”的“减法”运算变成了加法运算,也就弥补了之前我们原码所说的缺陷。

    补码的原理我们不必深究,有一个快速简洁求补码的方法我们需要记住:

    对于正数,不存在反码和补码,没有意义。因此,有些教材上说正数的反码补码形式相同是不对的,实际上,应该说正数没有反码补码更合适点。

    对于负数,其补码就是反码的最后一位 [加1] 所得。

    这里需要注意:最后一位若是0加1就是1,最后一位是1加1就进位变成0,看起来像取反一样,实际上进行的是操作.

     1.2 非数值信息在计算机系统中的表示

    在计算机内部,非数值信息也是采用0和 1 两个符号来进行编码表示的。

    ①字符的编码, ASCII码是“美国信息交换标准代码”的简称,在这种编码中,每个字符用 7 个二进制位表示,即从 0000000 到 1111111 可以给出 128 种编码,可用来表示 128 个不同的字符。一个字符的 ASCII码通常占用一个字节,由七位二进制数编码组成,故 ASCII 码最多可表示 128 个不同的符号。由于 ASCII码采用七位编码,来用到字节的最高位,故在计算机中一般保持为“0” ,在数据传输时可用作奇偶校验位。

    ② 汉字的编码,目前,我国使用的是“国家标准信息交换用汉字编码” ,该标准码是二字节码,用2个七位二进制数编码表示一个汉字,并收人了 6763 个汉字。汉字在计算机内的表示,有多种编码,如汉字输入码,输人码进人计算机后,必须转换成汉字内码,才能进行信息处理。为了最终显示、打印汉字,再由内码转换成汉字字形码。此外,为使不同的汉字处理系统之间能够交换信息,还必须设有汉字交换码。


     

    2. 内存地址和内存空间的简单理解

    2.1 理解内存地址和内存空间

    首先我们先来看这么一个代码

    
        int a =1,b=2;
        int main()
        {
            a++;
            b++;
            return 0;
        {

     

    这么一段简单的代码在计算机中如何执行呢?a和b在计算机中如何区分?要回答这个问题,必须要简单理解下计算机中的内存地址和内存空间。

    实际上,如果我们反汇编一下,就可以看到a++和b++分别对应的是:

        incl 0x80495f8              //把0x80495f8地址中的整数加1
        incl 0x80495fc              //把0x80495fc地址中的整数加1

    在这里,那0x80495f8地址和0x80495fc地址就叫做a和b在内存中的地址。要了解内存地址首先必须要知道的是,内存地址就只是一个编号,一个内存地址就代表一个内存空间。那么这个空间是多大呢?我们常说,计算机中存储器的容量是以字节为基本单位的。什么叫以字节为单位,就是说一个内存地址代表一个字节(1Byte 也就是 8bit)的存储空间,这就是我们说的字节Byte是计算机的基本单位的含义。

    1个内存地址 = 1个字节(Byte) = 8位(bit)

     我们还知道,int型是占据4个字节的(4字节Byte=32位bit),也就是说存储一个int型必须用4个字节,也就等价于至少占据4个内存地址,所以,int在计算机中存储是占据了4个内存地址的。我们在输入语句int a =1,b=2; 后,计算机就分别为a和b分配了4个内存地址来存储a和8,这一以来,我们只需要知道a和b的内存起始地址(首地址),再加4,就是a和b实际在计算机中的地址,如下图示:

    a和b在内存空间的地址

     再比如经常说32位的操作系统最多支持4GB的内存空间,也就是说CPU只能寻址2的32次方,即2的32次方个8bit单位,或者说最大只有2的32次方个内存地址。

                                                                  2的32次方Byte = 4GB =4 294 967 296Byte

    2.2 数据在内存的存储

    理解了内存地址和内存空间后,我们便能知道数据在计算机中到底最终是怎么存储的。

    学习编程,必须对内存的地址有一个透彻的理解。我们编程中的每一行代码,代码中用到的每个数据,都需要在内存上有其映射地址。当然,我们并不需要掌握内存是如何进行编址,那是计算机系中的另外一门课:操作系统的事了。

    内存地址:计算机把所有的信息都给数字化了,所以它知道自已把一个数据,一条命令记到了内存中的哪个(些)位置。

    看下面的例子,看计算机是如何在内存里记住变量a和变量b的:

    变量:(int) a = 4(int) b = 2
    内存地址:0x80495f80x80495f90x80495fa0x80495fb0x80495fc0x80495fd0x80495fe0x80495ff
    内存空间:2001H2002H2003H2004H2005H2006H2007H2008H
    内存数据:0000000000000000000000000000010000000000000000000000000000000010

     

    通过以上我们可以知道,int型变量a和b都占据了4个字节也就是4个内存空间,一个内存地址对应一个内存空间也对应一个字节即8个位。

    可以看到,(int) a 和 b 的确是由一串0、1组成的。更确切地,从图上可以看出它们分别都是由32位0和1组成。这32数都存放在4个内存地址里。所以,内存地址是内存当中存储数据的一个标识,并不是数据本身,通过内存地址可以找到内存当中存储的数据。

    展开全文
  • 转载一篇文章,留下来学习,加深...举例来说,+8在计算机表示为二进制的1000,那么-8怎么表示呢? 很容易想到,可以将一个二进制位(bit)专门规定为符号位,它等于0时就表示正数,等于1时就表示负数。比如,8位机

     转载一篇文章,留下来学习,加深下印象。

     

     问:

    负数在计算机中如何表示?

     

    举例来说,+8在计算机中表示为二进制的1000,那么-8怎么表示呢?

    很容易想到,可以将一个二进制位(bit)专门规定为符号位,它等于0时就表示正数,等于1时就表示负数。比如,在8位机中,规定每个字节的最高位为符号位。那么,+8就是00001000,而-8则是10001000。

    但是,随便找一本《计算机原理》,都会告诉你,实际上,计算机内部采用2的补码(Two's Complement)表示负数。

    什么是2的补码?

    它是一种数值的转换方法,要分二步完成:

    第一步,每一个二进制位都取相反值,0变成1,1变成0。比如,00001000的相反值就是11110111。

    第二步,将上一步得到的值加1。11110111就变成11111000。

    所以,00001000的2的补码就是11111000。也就是说,-8在计算机(8位机)中就是用11111000表示。

    不知道你怎么看,反正我觉得很奇怪,为什么要采用这么麻烦的方式表示负数,更直觉的方式难道不好吗?

    昨天,我在一本书里又看到了这个问题,然后就花了一点时间到网上找资料,现在总算彻底搞明白了。

    2的补码的好处

    首先,要明确一点。计算机内部用什么方式表示负数,其实是无所谓的。只要能够保持一一对应的关系,就可以用任意方式表示负数。所以,既然可以任意选择,那么理应选择一种最方便的方式。

    2的补码就是最方便的方式。它的便利体现在,所有的加法运算可以使用同一种电路完成。

    还是以-8作为例子。

    假定有两种表示方法。一种是直觉表示法,即10001000;另一种是2的补码表示法,即11111000。请问哪一种表示法在加法运算中更方便?

    随便写一个计算式,16 + (-8) = ?

    16的二进制表示是 00010000,所以用直觉表示法,加法就要写成:

     00010000
    +10001000
    ---------
     10011000

    可以看到,如果按照正常的加法规则,就会得到10011000的结果,转成十进制就是-24。显然,这是错误的答案。也就是说,在这种情况下,正常的加法规则不适用于正数与负数的加法,因此必须制定两套运算规则,一套用于正数加正数,还有一套用于正数加负数。从电路上说,就是必须为加法运算做两种电路。

    现在,再来看2的补码表示法。

     00010000
    +11111000
    ---------
    100001000

    可以看到,按照正常的加法规则,得到的结果是100001000。注意,这是一个9位的二进制数。我们已经假定这是一台8位机,因此最高的第9位是一个溢出位,会被自动舍去。所以,结果就变成了00001000,转成十进制正好是8,也就是16 + (-8) 的正确答案。这说明了,2的补码表示法可以将加法运算规则,扩展到整个整数集,从而用一套电路就可以实现全部整数的加法。

    2的补码的本质

    在回答2的补码为什么能正确实现加法运算之前,我们先看看它的本质,也就是那两个步骤的转换方法是怎么来的。

    要将正数转成对应的负数,其实只要用0减去这个数就可以了。比如,-8其实就是0-8。

    已知8的二进制是00001000,-8就可以用下面的式子求出:

     00000000
    -00001000
    ---------

    因为00000000(被减数)小于0000100(减数),所以不够减。请回忆一下小学算术,如果被减数的某一位小于减数,我们怎么办?很简单,问上一位借1就可以了。

    所以,0000000也问上一位借了1,也就是说,被减数其实是100000000,算式也就改写成:

    100000000
    -00001000
    ---------
     11111000

    进一步观察,可以发现100000000 = 11111111 + 1,所以上面的式子可以拆成两个:

     11111111
    -00001000
    ---------
     11110111
    +00000001
    ---------
     11111000

    2的补码的两个转换步骤就是这么来的。

    为什么正数加法适用于2的补码?

    实际上,我们要证明的是,X-Y或X+(-Y)可以用X加上Y的2的补码完成。

    Y的2的补码等于(11111111-Y)+1。所以,X加上Y的2的补码,就等于:

    X + (11111111-Y) + 1

    我们假定这个算式的结果等于Z,即 Z = X + (11111111-Y) + 1

    接下来,分成两种情况讨论。

    第一种情况,如果X小于Y,那么Z是一个负数。这时,我们就对Z采用2的补码的逆运算,求出它对应的正数绝对值,再在前面加上负号就行了。所以,

    Z = -[11111111-(Z-1)] = -[11111111-(X + (11111111-Y) + 1-1)] = X - Y

    第二种情况,如果X大于Y,这意味着Z肯定大于11111111,但是我们规定了这是8位机,最高的第9位是溢出位,必须被舍去,这相当于减去100000000。所以,

    Z = Z - 100000000 = X + (11111111-Y) + 1 - 100000000 = X - Y

    这就证明了,在正常的加法规则下,可以利用2的补码得到正数与负数相加的正确结果。换言之,计算机只要部署加法电路和补码电路,就可以完成所有整数的加法。

    转自

    http://blog.csdn.net/gaochizhen33/article/details/7161417

     

     

    另记载下反码的规律

    ~ (反码): 01001 ~ 后 10110,即1变0 , 0变1
    6反码结果是-7, 整数a的反码结果= -a -1
    (~6) = -7
      -6 = -7 + 1;
    (~8) = -9:-8 = -9 + 1;
    (~16) = -17:-16 = -17 + 1;

    ~(-6)= -(-6)-1=5 ;
     (~a)先把a变为-a,-a - 1 = (~a);

     

     

    展开全文
  • 在计算机中,一切数据都是以二进制的形式进行表示,小数也不例外。 但是像1011.0011这样带小数点的表现形式,完全是纸面上的二进制数表现形式,在计算机内部是无法直接使用的,且计算机若采用定点数的形式来表示小数...

    参考书籍 《程序是怎样跑起来的》

    二进制小数表示

    在计算机中,一切数据都是以二进制的形式进行表示,小数也不例外。
    若将一个十进制的小数化为二进制小数,其简单规则如下图所示:
    在这里插入图片描述
    但是像1011.0011这样带小数点的表现形式,完全是纸面上的二进制数表现形式,在计算机内部是无法直接使用的,且计算机若采用定点数的形式来表示小数的话,则限制了其表示范围以及空间分配的不合理;
    那么如何更加有效地描述小数呢?

    浮点数的基本概念

    在很多编程语言中都提供了两种表示小数的数据类型,分别是双精度浮点数和单精度浮点数。双精度浮点数类型用64位、单精度浮点数类型用32位来表示全体小数。
    在C语言中,双精度浮点数类型和单精度浮点数类型分别用doublefloat来表示。这些数据类型都采用所谓的浮点数来表示小数。那么,浮点数到底是什么呢?

    0.12345 × 1 0 3 和 0.12345 × 1 0 − 1 0.12345×10^3 和0.12345×10^{-1} 0.12345×1030.12345×101这样使用与实际小数点位置不同的书写方法来表示小数的形式称为浮点数。
    与浮点数相对的是定点数,使用定点数表示小数时,小数点的实际位置固定不变。例如, 0.12345 × 1 0 3 和 0.12345 × 1 0 − 1 0.12345×10^3和0.12345×10^{-1} 0.12345×1030.12345×101用定点数来表示的话即为123.45和0.012345。

    这样,浮点数是指用符号、尾数、基数和指数这四部分来表示的小数。因为计算机内部使用的是二进制数,所以基数自然就是2。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bEiyM0y2-1573529886592)(file:///C:/Users/Wangxiaoke/AppData/Local/Packages/Microsoft.Office.OneNote_8wekyb3d8bbwe/TempState/msohtmlclip/clip_image001.png)]

    因此,实际的数据中往往不考虑基数,只用符号、尾数、指数这三部分即可表示浮点数。也就是说,64位(双精度浮点数)和32位(单精度浮点数)的数据,会被分为三部分来使用。

    IEEE 32 与 IEEE 64

    前面提到了,在计算机中实际上有两种浮点数标准,分别为双精度浮点数(64位)与单精度浮点数(32位),并且实际存储的内容为符号、指数以及尾数三个部分:


    在这里插入图片描述

    双精度浮点数能够表示的正数范围是 4.94065645841247 × 1 0 − 324 4.94065645841247×10^{-324} 4.94065645841247×10324 ~ 1.79769313486232 × 1 0 308 1.79769313486232×10^{308} 1.79769313486232×10308,负数范围是 − 1.79769313486232 × 1 0 308 -1.79769313486232×10^{308} 1.79769313486232×10308 ~ − 4.94065645841247 × 1 0 − 324 -4.94065645841247×10^{-324} 4.94065645841247×10324
    单精度浮点数能够表示的正数范围是 1.401298 × 1 0 − 45 1.401298×10^{-45} 1.401298×1045 ~ 3.402823 × 1 0 38 3.402823×10^{38} 3.402823×1038,负数范围是 − 3.402823 × 1 0 38 -3.402823×10^{38} 3.402823×1038 ~ − 1.401298 × 1 0 − 45 -1.401298×10^{-45} 1.401298×1045
    并且在这些范围中,有些数值是无法准确表示的,如 0.1 等,故而在使用浮点数做运算的时候需要额外留意。

    符号部分的规则

    符号部分的规则比较简单,用1表示负数,0表示正数。

    指数部分的规则

    指数部分采用"EXCESS"系统表现。
    所谓EXCESS是“剩余的”的意思。简单来讲,就是在一个范围中找到一个中间值来表示0,那么小于这个中间值的为负值,大于这个中间值的为正值。
    使用这种方法主要是为了表示负数时不使用符号位。在某些情况下,在指数部分,需要通过“负xx次幂”的形式来表示负数。EXCESS系统表现是指,通过将指数部分表示范围的中间值设为0,使得负数不需要用符号来表示。

    在这里插入图片描述

    也就是说,当指数部分是8位的单精度浮点数时,最大值11111111=255的1/2,即01111111=127(小数部分舍弃)表示的是0,指数部分是11位的双精度浮点数时,11111111111=2047的1/2,即01111111111=1023(小数部分舍弃)表示的是0。

    尾数部分的规则

    尾数部分使用的是将小数点前面的值固定为1的正则表达式。

    在这里插入图片描述
    具体来讲,就是将二进制数表示的小数左移或右移(这里是逻辑移位。因为符号位是独立的“)数次后,整数部分的第1位为1,其他位均为0)。
    而由于第1位必须是1,第1位的1在实际的数据中无需保存。
    并且不难理解的是,向左移n次则最终指数部分的实际值为 -n,向右移n次则最终指数部分的实际值为 n

    总结

    小数是以浮点数的形式在计算机中表示,而浮点数在计算机中的表示则通过特定的格式与规则来进行存储:


    在这里插入图片描述

    也正因如此,我们可以知道诸如0.1这种小数是无法在计算机中准确描述的,所以在遇到浮点数比较与计算等问题时,要额外注意出错的情况,能转换成整数运算的尽量转换成整数运算。

    展开全文
  • 浮点数在计算机中的表示

    万次阅读 多人点赞 2018-07-23 22:44:11
    1.1 浮点数在计算机中的表示 1.1.1 指数偏移值 1.1.2 规约浮点数[1] 1.1.3 非规约浮点数 1.2 单精度和双精度浮点数 1.3 浮点数转二进制 1.3.1 无小数浮点数转二进制表示 1.3.2 含小数浮点数转二进制表示 1.4 ...

    浮点数

    早期的计算机使用定点数来表示实数,由于定点数的小数点位置固定,而计算机字长有限,定点数无法表示很大和很小的实数,因此而在计算机科学中有了对于实数近似值数值的表示法——浮点数。这种表示法类似于十进制中的科学计数法——它的优点是数的数量级、精确度以及数值都非常准确,浮点数表示其基数为 2 2 ,因此一个浮点数 a 由两个数 m m e 来表示: a=m×be a = m × b e ,其中 b b 表示基数,m 称为尾数。下面对浮点数在计算机中的表示详细介绍。

    1.1 浮点数在计算机中的表示

    浮点数可以这样表示[1]

    Value=sign×exponent×fraction V a l u e = s i g n × e x p o n e n t × f r a c t i o n

    也就是说浮点数的实际值等于,符号值乘以指数偏移值,再乘以分数值。

    我们知道当前绝大多数计算机(据说有过三进制计算机[7])的数据都是二进制编码(0 和 1),在计算机中,二进制的浮点数按照以上公式在一定字长内(单精度浮点数32位,双精度浮点数64位)分别存储“符号位(sign bit)”,“指数部分”——次高有效的 e 个比特,以及“有效数(significand)”的小数部分——非规约数(稍后介绍)整数部分为 0,其他整数部分一律为 1。存储形式如下图所示:

    (图片引用自[1]

    1.1.1 指数偏移值

    这里着重介绍关于“指数部分”的偏移量,IEEE754 中规定,单精度浮点数的指数域是 8 个比特,因此它的指数偏移值为 2811=127 2 8 − 1 − 1 = 127 ,64 位双精度浮点数的值数域是 11 个比特,它的指数偏移值为 21111=1023 2 11 − 1 − 1 = 1023 为什么要指数编码时需要加上一个偏移值?

    我们知道,在 10 进制的科学计数法中,指数可以是负数,而计算机存储浮点数的“指数部分”又是一个无符号的整数,因此,在 IEEE754 标准规定,exponent 必须减去一个偏移值而得到真实的“指数值”。

    为什么单精度浮点数指数偏移值是 127,双精度浮点数指数偏移值是 1023 呢? IEEE754 标准规定了几个特殊值[1]:

    • 如果指数是 0 并且尾数的小数部分是 0,这个数是 ±0(和符号位有关)。
    • 如果指数 =2e1 = 2 e − 1 并且尾数的小数部分是 0,这个数是 ±∞(同样和符号位有关)。
    • 如果指数 =2e1 = 2 e − 1 并且尾数的小数部分非 0,这个数表示为不是一个数 NaN。
      (注意,这里所说的指数是指编码后的指数值(即阶码),而非指数真值,务必了解清楚。)

    [8]这就意味着,单精度浮点数的 8 位阶码(即移码表示的指数部分)除特殊值外所表示范围为 (1,254) ( 1 , 254 ) ,我们知道 8 位有符号数的补码取值范围是 (128,+127) ( − 128 , + 127 ) , 假设偏移值是 +128,在表示真值 +127 时阶码为 1111 1111,显然,根据 IEEE754 标准,255 是保留数值,偏移值是 +128 表达 +127时产生了上溢。与此同时,偏移值为 +127,在表达 -127 时,阶码为 0000 0000,同样依据 IEEE754 标准,0 也是保留数值,于是产生了下溢(更无法表达 -128 真值),因此阶码真值去掉 -127 和 -128,其取值范围为 (126,+127) ( − 126 , + 127 )

    此外,关于偏移量取值为 127 而不是 128 有另一种说法:为了使浮点数上下(正负)取值范围相对对称[9],相对而言,更倾向上文的说法。

    为什么计算机存储浮点数的“指数部分”要用移码表示?

    有符号数的原码、反码和补码一个共同特点是将符号作为最高位,与数值部分一起编码,正好是 “0”,负号是 “1”。这样在比较不同符号数据时比较麻烦,机器认为 “1” 比 “0” 大,因此,正负数比较时可能得到的结果是负数比较大,这显然不合理,而移码和补码的区别是符号位刚好相反,这样,便可以直接使用移码对不同符号数据进行比较了。

    1.1.2 规约浮点数[1]

    规约——指用唯一确定的浮点形式表示一个值。 wiki 中对规约浮点数做了说明:如果指数编码值在区间 0<exponent<2e2 0 < e x p o n e n t < 2 e − 2 之间(例如,单精度浮点数,其指数编码值区间为 0<e<255 0 < e < 255 ),且在科学计数法表示下,其分数的最高有效位为 是 1。(注意一点,规约浮点数尾数的最高有效位 1 是隐藏的。)

    1.1.3 非规约浮点数

    如果浮点数指数部分编码值是 0,分数部分非 0,那么这样的浮点数称为非规约浮点数。IEEE754 标准规定,非规约浮点数指数偏移值比规约浮点数指数偏移值小 1,例如,单精度规约浮点数其指数偏移值是 127,其非规约浮点数指数偏移值就是 126,这也就意味着,非规约浮点数的指数真值是 -126,这也其指数编码值刚好是 0。

    非规约浮点数有两个作用一是提供了表示数值 0 的方法,因为规约浮点数规定了尾数 1 ≥ 1 ,因此规约浮点数不能表示数值 0,当阶码字段全为 0 时(这表明该浮点数是一个非规约浮点数),尾数有效位也是 0 时,该浮点数绝对值是 0,再结合符号位,我们可以得到 ±0 ± 0

    非规约数第二个作用是可以表示接近 0 的数值,它比最小规约浮点数更趋近 0,IEEE754-1985 标准使用非规约浮点数填补最小规约数与 0 的距离,非规约浮点数提供了一种属性称为“逐渐式下溢出(gradual underflow)”,所有可能的数值均分分布的接近 0,否则会发生“突然式下溢出(abrupt underflow)”,对于单精度浮点数,我们知道最小规约浮点数的绝对值是 1.0×2126 1.0 × 2 − 126 (尾数真值是 1.0,指数真值是 1),次小的最小规约浮点数是 1.0×2126×223 1.0 × 2 − 126 × 2 − 23 ,会发现最小规约浮点数 与 0 的距离是与相邻次小规约浮点数距离的 223 2 23 倍,非常突然的下溢出到 0,这会造成一种情况,两个小浮点数 X X Y (在区间 [1.0×2126,1.0×2126] [ − 1.0 × 2 − 126 , 1.0 × 2 − 126 ] 内)相减的结果为 0,显然这不合理,非规约浮点数可以解决该问题,依据非规约浮点数的定义(注意非规约浮点数指数编码值是 0,其实际值是 -126),它的最大和最小绝对值表示分别为: (1.0223)×2126 ( 1.0 − 2 − 23 ) × 2 − 126 223×2126 2 − 23 × 2 − 126 ,这些数值相邻距离是 2149 2 − 149 ,最小非规约浮点数绝对值和 0 的距离也是 2149 2 − 149 ,因此,非规约浮点数扩大了 0 附近的浮点数表示范围。

    为什么非规约浮点数这样设置指数偏移值( Bias1 B i a s − 1 ,这里注意下,在有些教程中偏移值是负值 1Bias 1 − B i a s )?

    这种方式提供了一种从非规格化数值平滑转换到规格化数值的方法。《深入理解计算机系统》第三章 81 页以 8 位浮点数举例,假设其阶码占 4 位,小数位占 3 位,计算出来最大的非规约浮点数为 7512 7 512 ,最小的规约浮点数为 8512 8 512 ,从非规约浮点数到规约浮点数的平滑转变归功于将指数 E E 定义为 1Bias Bias1 B i a s − 1 ),而不是 Bias − B i a s Bias B i a s ),这样可以补偿非规约浮点数尾数没有隐含的开头 1。最大非规约浮点数和最小规约浮点数的阶码相同,并且其尾数刚好相差 2n 2 − n (尾数占位是 n,以上文 8 位浮点数举例,小数占 3 位,则最大非规约浮点数尾数为 0.111,最小规约浮点数尾数为 1.000,两者之差刚好是 23 2 − 3 ),这样正好可以完成非规约浮点数到规约浮点数的平滑过渡。

    1.2 单精度和双精度浮点数

    C/C++ 中 float 和 double 分别表示单精度类型浮点数和双精度类型浮点数,float 是 32 位 4 个字节,double 是 64 位 8 个字节,在 IEEE754[1] 标准规范中它们的“符号位”,“指数部分”以及“尾数”(即小数部分)占位如下:

    (图片引用自[1]

    (图片引用自[1]

    1.3 浮点数转二进制

    假设我们有一个 10 进制浮点数 x=12.34 x = 12.34 x x 的整数部分可以表示为 1×101+2×100,小数部分可以表示为 3×101+4×102 3 × 10 − 1 + 4 × 10 − 2 ,类似推广到其他进制表示,例如我们有一个二进制数 110.011 110.011 ,其整数部分可以表示为 1×22+1×21+0×20 1 × 2 2 + 1 × 2 1 + 0 × 2 0 ,小数部分表示为 0×21+1×22+1×23 0 × 2 − 1 + 1 × 2 − 2 + 1 × 2 − 3 。其他进制表示同理。(注意,我们通常习惯的运算是基于 10 进制的,以上进制的运算表达式所得数值也是 10进制。)

    (图片引用自[10]
    28 的三进制表示即为 1001 (通常高位在左,低位在右),三进制 1001 可表示为: 1×33+0×32+0×31+1×30 1 × 3 3 + 0 × 3 2 + 0 × 3 1 + 1 × 3 0 ,可以看出以上短除法运算过程其实是三进制整数转换为 10 进制数的逆过程。

    对于小数部分,如何从 10 进制转换为二进制表示?回顾上文,采用乘 2 取整法,即将小数部分乘以 2,取结果的整数部分,剩下的小数部分继续乘以 2,再取整数部分,一直循环,知道小数部分为 0,如果小数部分一直不能为 0,就需要按照保留位数,对保留位之外的数值原则上舍 0 入 1。最后对全部所取整数从第一个到最后一个依次排列,这一点与短除法转换 10 进制整数刚好相反。

    1.3.1 无小数浮点数转二进制表示

    依据 IEEE754 标准,我们知道浮点数有几个特殊值,比如数值 0,单精度浮点数的表示为:

    s0|e00000000|f00000000000000000000000. s e f 0 | 0000 0000 | 000 0000 0000 0000 0000 0000.

    其他浮点数特殊值都有其对应二进制表示。

    那么对于一个普通的无小数浮点数,例如 12.0 12.0 ,如何将其转换成二进制表示呢?该浮点数整数部分是 12 12 ,小数部分是 0 0 ,首先将它们分别转换为二进制表示。

    利用短除法,10 进制数 12 可以表示为: 1100 1100 ,因为无小数, 12.0 12.0 二进制表示为 1100.0 1100.0 ,根据 IEEE754 标准,规约浮点数尾数有一个隐含的高位 1,所以小数点向左移动三位, 12.0 12.0 就表示为 1.100×23 1.100 × 2 3 ,以单精度浮点数为例,尾数 23 位,指数偏移值是127,尾数 M=.100 M = .100 后面补 0 直到总共有 23 位,指数编码值 e=3+127=130 e = 3 + 127 = 130 ,最后我们得到:

    0|10000010|10000000000000000000000. 0 | 1000 0010 | 1000 0000 0000 0000 0000 000.

    1.3.2 含小数浮点数转二进制表示

    对于含小数的浮点数,需要将整数部分和小数部分分开处理,上文也分别介绍过两者转换二进制表示的方法,这里不再赘述。整数和小数部分都成功表示为二进制之后,依据 IEEE754 标准,规约化浮点数,最后可得到浮点数在计算机中的存储。

    1.4 浮点数的精度

    前文我们曾以单精度浮点数举例,相邻规约浮点数间的距离是 223 2 − 23 ,显然,浮点数不能表示所有的实数。我们知道,如果浮点数的小数部分能够在有限位内转换为二进制数,则浮点数在计算机中是精确表示的。然而,实际上不是所有的小数都可以在有限位内转换为二进制数,前文介绍过保留位之外取得的数值原则上舍 0 取 1,这样截断必然会造成精度的缺失。如果想要得到更精确的浮点数表示,只能依靠不断增加小数有效位,这也就是双精度浮点数比单精度浮点数更精确的原因。

    例如,10 进制小数 0.1,我们使用乘 2 取整的方法,发现小数部分永远无法乘尽,最后会得到无限循环的 (0011) ( 0011 )

    1.5 浮点数运算

    首先我们明确浮点数的精度问题浮点数运算不遵循结合律和分配律,例如两个浮点数运算由于精度限制可能会产生“舍入”行为,另外我们经常说浮点运算比整数运算要慢,可是慢在哪里却不了解。下面将针对性介绍浮点运算的规则。

    1.5.1 浮点加减运算

    通过前文我们了解到计算机中浮点数阶码直接反应了实际尾数有效值小数点的位置,因此,当两个阶码不同的浮点数加减时,尾数不能直接进行加减运算,浮点加减运算必须按照以下几步进行[13]

    • 对阶,目的是使两个浮点数小数点位置对其,即使两个浮点数阶码相等。
      阶码对齐的原则是小阶向大阶看齐,所以,尾数每向右移 1 位,其对应阶码加 1。
    • 尾数求和,尾数求和依照定点运算[13](第 6 章“定点运算”)方式进行加减运算。
    • 规格化(规约化),尾数求和后我们需要依照 IEEE754 标准对求和结果规约化。
      左规:尾数左移一位,阶码减 1。
      右规:尾数右移一位,阶码加1。
    • 舍入,要考虑尾数右移丢失的数值,在有限位字长内保证浮点数的精度,前文介绍过,保留位之后的数值原则上“舍 0 取 1”。
    • 溢出判断,判断加减结果是否溢出。
      补码定点加减运算的溢出判断通常有两种方式:一、使用一个符号位时,溢出只可能发生在正正相加,负负相加,以及正负相减的情形,通常以最高有效位产生的进位和符号位产生的进位异或操作,若结果为 1 表示溢出,结果为 0 表示无溢出;二、使用双符号位,双符号位高位符号发生进位时,自然丢掉,且高位符号位是真正的符号位,当两个符号位不同时则表示发生了溢出。
      浮点数的溢出判断是根据阶码来判断是否溢出的。形如 01.xxxxxx... 01. x x x x x x . . . 10.xxxxxxx... 10. x x x x x x x . . . 的尾数并不表示溢出,只需要右规完成规格化,再根据阶码来判断浮点数是否溢出。一般来说,浮点数下溢指的是数值接近 0,一般将其作为机器零处理,浮点数真正的溢出指的是上溢。
    1.5.2 浮点乘除运算

    和浮点加减法一样,浮点乘除运算分别对阶码进行加减运算和对尾数进行乘除运算。

    • 阶码运算。
      从上文我们知道阶码中计算机中使用移码存储,如果我们用双符号位表示阶码,即在原移码最高位前加一个符号位,该位恒为 0,如果运算之后,最高符号位变成了 1,则表示溢出,这时低位符号位为 0 表示上溢;低位符号位为 1 表示下溢。若最高符号位是 0,则表示没有溢出,这时低位符号位为 1 表示结果为正;低位符号位为 0 表示结果为负。
    • 尾数运算。
      尾数运算可参考定点小数乘除法。运算结果可能要进行左规,左规后还可能涉及到尾数舍入的问题,这时有两种处理方式,一是直接丢弃有效尾数位之外的数值,这种方式影响精度;二是采用浮点加减运算中介绍的舍入规则。

    1.6 规约浮点数和非规约浮点数运算效率[12]

    引文中举出了一段比较规约浮点数和非规约浮点书运算效率的代码。

    Reference

    [1]. IEEE754-wiki
    [2]. 浮点数-wiki
    [3]. 科学计数法-wiki
    [4]. 定点数运算
    [5]. 关于2的补码
    [6]. 原码、补码、反码
    [7]. 三进制计算机
    [8]. 阶码偏移量为什么是127/1023
    [9]. 阶码偏移量是 127 而不是 128 的另一种说法
    [10]. 有趣的二进制
    [11]. 你应该知道的浮点数基础知识
    [12]. 除法-短除法(Wiki)
    [13]. 计算机组成原理-唐朔飞

    展开全文
  • 比如,每一个字符文本块中都是用一个数字表示的。图片也不例外,在计算机中,每个图片也是用一系列数字表示的。一张图片被分裂成许多成千的,甚至上万的基础图片元素叫像素,英文是 pixels,每一个像素是一个立方体...
  • 想必大家都知道计算机内部是由 IC 这种电子部件构成的。CPU(微处理器)和内存也是IC的一种。IC有几种不同的形状,有的像一条黑色蜈蚣,其两侧有数个乃至数百个引脚;有的则像插花用的针盘,引脚IC内部并排排列...
  • 计算机信息表示与存储

    千次阅读 2005-02-24 10:39:00
    无论哪一种数据在计算机中都是用二进制数码表示的。计算机中只有二进制数值,所有的符号都是用二进制数值代码表示的,数的正、负号也是用二进制代码表示。数值的最高位用“0”、“1”分别表示数的正、负号。
  • 本章主要研究了计算机中无符号数,补码,浮点数的编码方式,通过研究数字的实际编码方式,我们能够了解计算机中不同类型的数据可表示的值的范围,不同算术运算的属性,可以知道计算机是如何处理数据溢出的。...
  • 文章目录一、数值及其转换1. 计算机内数据的处理形式2. 计算机内部采用二进制的原因3. 基数与数码4. 常用进制标识符5. 二进制逻辑运算规则6....(1)在计算机内,不管你是怎样的数据,都采用二进制编码形式表示和处理。
  • 例如《C Primer Plus》一书中,写到包含头文件时,可以直接指定头文件的路径,如 #include “/usr/biff/p.h”。  这个和我们平时Windows系统中... 那到底是什么会采用不同的表示方式了?  UNIX 操作系统设
  • 学习的计算机体系结构的时候,肯定会遇到数制的表示问题,其中最常见的就是定点数和浮点数的表示问题,定点数的表示很简单,有很多资料,浮点数的表示也不难,只是稍稍复杂,网上和书本中也有很多资料,这里再简单...
  • 数据在计算机中存储形式

    千次阅读 2019-03-02 16:46:12
    数据在计算机中都是以二进制码存储的。 对于数,是以二进制的补码存储的。 对于有符号的数,其范围是-128~127 因为补码 0000 0000代表0 所以补码 1000 0000被定义-128 其他的补码各自代表一个八位二进制的数字。 ...
  • 数据在计算机中的存储方式

    千次阅读 2014-09-30 17:17:34
     数据有数值型和非数值型两类,这些数据在计算机中都必须以二进制形式表示。一串二进制数既可表示数量值,也可表示一个字符、汉字或其他。一串二进制数代表的数据不同,含义也不同。这些数据计算机的存储设备中是...
  • 最近做一个网络通信的模块,众所周知,网络通信中,大部分大部分数值的表示范围都限于一个字节之内,而一个字节即8位,能够表示256个数字,但通信传输的过程中都是二进制,即01010组合,这样的话,能够表示的...
  • 而我们傻蛋计算机根本不认识十进制的数据,他只认识0,1,所以在计算机存储中,首先要将上面的数更改为二进制的科学计数 法表示,8.25用二进制表示可表示为1000.01,我靠,不会连这都不会转换吧?那我估计要没辙了。...
  • Java中的负数的在计算机中的二进制表示,以及与十进制的相互转换
  • 计算机如何表示浮点数(小数)

    万次阅读 2015-12-02 19:58:38
    C语言和C#语言中,对于浮点类型的数据采用单精度类型(float)和双精度类型(double)来存储,float数据占用32bit,double数据占用64bit,我们声明一个变量float f= 2.25f的时候,是如何分配内存的呢?如果胡乱分配,...
  •   众所周知,计算机中的数据,指令都是二进制形式的,什么我们日常生活中都是十进制的,而计算机偏偏采用二进制呢?从某种角度上来说,算是不得已而为之。追溯到远古,我们的祖先们采用十进制的原因我猜想大概率是...
  • 计算机网络基础:这是一份详细 HTTP 学习指南

    万次阅读 多人点赞 2018-08-27 08:35:47
    关于计算机网络,HTTP网络通信协议在任何的开发工作中都非常重要 今天,我将献上一份HTTP的学习指南,希望你们会喜欢 目录 1. 储备知识 讲解HTPP协议前,先了解一些基础的计算机网络相关知识 1.1 ...
  • 通常计算机编程语言中都建议不要比较基本类型float的大小,特别是不要用等号来比较。(BigDecimal等对象类型例外,因为它已经不是采用IEEE 754标准表示法) 举例说明:  十进制小数: 12.75 表示 1*10^1 ...
  • 任何计算机都必须加载相应的操作系统之后,才能构成一个可以运转的、完整的计算机系统。操作系统的功能是否强大,决定了计算机系统的综合能力;操作系统的性能高低,决定了整个计算机系统的性能;操作系统本身的...
  • 离散数学在计算机科学中的应用

    万次阅读 多人点赞 2018-02-03 11:56:44
    这次离散数学的最后一题是:利用本学期学到的离散数学的知识阐释其一个软件工程中的应用。 下面说说离散数学的应用。 离散数学数据结构中的应用 数据结构中将操作对象间的关系分为四类:集合、线性结构、树形...
  • 如何学习离散数学和在计算机科学中应用

    万次阅读 多人点赞 2014-12-18 20:45:26
    各学科领域,特别在计算机科学与技术领域有着广泛的应用,同时离散数学也是计算机专业的许多专业课程,如程序设计语言、数据结构、操作系统、编译技术、人工智能、数据库、算法设计与分析、理论计算机科学基础等...
  • 计算机网络基础知识总结

    万次阅读 多人点赞 2020-10-20 07:40:54
    如果说计算机把我们从工业时代带到了信息时代,那么计算机网络就可以说把我们带到了网络时代。随着使用计算机人数的不断增加,计算机也经历了一系列的发展,从大型通用计算机 -> 超级计算机 -> 小型机 -> ...
  • 数据在计算机内存中的存储形式

    千次阅读 2019-05-07 14:19:25
    计算机要处理的信息是多种多样的,如数字、文字、符号、图形、音频、视频等,这些信息在人们的眼里是不同的。但对于计算机来说,它们在内存中都是一样的,都是以二进制的形式来表示。   要想学习编程,就必须了解...
  • 计算机网络知识点汇总(谢希仁 第七版)

    万次阅读 多人点赞 2018-09-18 17:34:34
    前面 这篇博客是当时大二的时候为了学习计网总结的一篇学习笔记,其实当时的做法和抄书差不多,但是时隔两年的时间没想到有这么多的 同学会来关注学习,实在受宠若惊;...二·重难点的部分加上详...
  • 浮点数(小数)在计算机中如何用二进制存储?

    千次阅读 多人点赞 2020-08-28 22:39:12
    浮点数在计算机中如何用二进制存储? 前言 前面我有篇博文详解了二进制数,以及如何同二进制数表示整数。但是,计算机处理的不仅仅是整数,还有小数,同样小数在计算机也是用二进制进行存储的,但是,二进制如何去...
  • 前言HTTP网络通信协议在任何的开发工作中都起到非常重要的作用,今天,我们来讲解下关于HTTP的相关知识。目录计算机网络相关知识计算机网络体系结构分为五层,自上而下分别是应用、运输、网络、数据链路和物理层,如...
  • 面试官:“谈谈Spring中都用到了那些设计模式?”。

    万次阅读 多人点赞 2019-05-23 20:51:14
    我自己总结的Java学习的系统知识点以及面试问题,已经开源,目前已经 41k+ Star。... JDK 中用到了那些设计模式?Spring 中用到了那些设计模式...我网上搜索了一下关于 Spring 中设计模式的讲解几乎都是千篇一律,而且...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 96,271
精华内容 38,508
关键字:

任何信息在计算机中都表示为