浮点数_浮点数规格化 - CSDN
精华内容
参与话题
  • 浮点数

    千次阅读 2019-12-12 20:52:24
    计算机有两种小数,定点数和浮点数。 定点数指的是小数点后面的位数是固定的。对十进制进行BCD编码,然后加上符号位,0表示正数,1表示负数,转为BCD编码后如果加上4bit符号位是整数字节的话就用4bit,否则用8Bit。 ...

    定点数

    计算机有两种小数,定点数和浮点数。

    定点数指的是小数点后面的位数是固定的。小数点固定在数据的最高位就是定点小数,固定在小数点最高位的称为定点整数。

    定点小数是纯小数,所以它的范围是[2-n,1-2-n]
    在这里插入图片描述
    定点小数是纯整数,所以它的范围是[1,2n-1]
    在这里插入图片描述

    对十进制进行BCD编码,然后加上符号位,0表示正数,1表示负数,转为BCD编码后如果加上4bit符号位是整数字节的话就用4bit,否则用8Bit。

    如-9.99进行编码后是1.5个字节,那么就用4bit表示符号位,0001-1001-1001-1001,如-99.99进行BCD编码是2个字节那么就用8bit表示符号位,0000-0001-1001-1001-1001-1001。

    显而易见定点数可以表示任何小数,但是如果数字过大或者小数后面位数过多那么就需要很多字节来存储,这可能就是浮点出现的原因。

    浮点数

    应用更广、更加复杂。浮点数之所以存储字节相对来说比定点数少,是因为它不是硬生生的去表达小数,使用了科学计数法一些约定来表达小数。

    浮点数由符号位、有效数字、指数来表示,有效数字在[1,9]区间内,可以看出表示不了0,但是可以通过规定产生。

    浮点数标准是IEEE754,规定了4种浮点数类型:单精度、双精度、延伸单精度、延伸双精度。最长用的是单精度、双精度,下面将介绍单精度。

    计算机世界由二进制来表示十进制,指数称为阶码、有效数称为尾数。

    单精度分配了4个字节,一共32位,1位符号位,8位指数位,23位有效数字位。

    符号位

    最高1位表示,0正数,1负数。

    阶码位

    在符号位的右侧8位用来存储指数,IEEE754标准规定这8位是指数正向偏移到正域,8位二进制能表示[-128,127]偏移到正域就需加128变成[0,255],用0表示机器0,全1代表无穷大,所以得去头去尾,所以偏移量为2n-1 -1而不是2n-1,所以E=e+2n-1 -1,得到的指数范围为[-127,126]

    尾数位

    IEEE754规定尾数用源码表示

    规范化

    最终格式是± 1.bbb…*2p
    ±用符号位表示
    p是加上偏移量对应的阶码
    b是尾数由于最左边规定总是1所以用23位全部表示b。

    举个例子

    3.14
    尾数3用11表示,0.14最近的是2-3=0.125 还差0.015,2-7=0.0078125还差0.0071875,2-8=0.00390625,依次类推最终表示为0.0010001111010111000010[10001111…]
    这样3.14的二进制代码就是:11.0010001111010111000010[10001111…]规则化后1.10010001111010111000010[10001111…]*21这边先舍入后面再讲为啥,尾数为10010001111010111000011,阶码是1加上偏移量127就是128为1000 0000,符号位为0,那么结果就是0100-0000-0100-1000-1111-0101-1100-0011转为十进制是:3.1400001049041748046875,和3.14是有误差的。

    舍入

    舍入的目的主要是可能尾数过长,然后舍入的原则是保证一定的精度。所以规定相对误差不能超过一般机器ε的一半,3.14的相对舍入误差0.0000001049041748046875/3.14≈0.00000003340897286773,单精度的机器ε为2-23≈1.1920928955078125e-7,它的一半是0.00000005960464477539,显然上面舍入是符合要求的。

    浮点数加减运算

    零值检测

    浮点数运算比较复杂,检测0值(规定阶码和尾数全为0)直接能得出结果。

    对阶操作

    如果阶码不一样就做不了求和操作,所以需要对齐,对阶可以将尾数左移右移,由于左移会移出高位这样会造成误差更大,所以IEEE754规定移动方向为右移动,即选择阶码小的数进行移动。

    尾数求和

    对阶完后,直接按位相加即可完成求和(如果是负数则需要进行转补码),和十进制类似如9.8103与0.6103结果为10.4*103

    结果规整化

    尾数向右移动称为右规,向左称为左规,比如上面结果需要右规1.04*104

    现在把单精度1-0.9来推演下,为啥是0.100000024呢?

    1用浮点数表示是
    符号位0
    阶码位是0加上移码127是0111-1111
    尾数1.000-0000-0000-0000-0000-0000
    结果是0011-1111-1000-0000-0000-0000-0000-0000
    -0.9用浮点数表示是
    结果是1011-1111-0110-0110-0110-0110-0110-0110

    由于1的阶码还原后是0,-0.9还原后是-1,所以需要将-0.9尾数的补码
    移动一位,尾数位最左端存在一个隐藏位,1110-0110-0110-0110-0110,
    由于需要相加需要转补码0001-1001-1001-1001-1001-1010向右移动
    一位之后0000-1100-1100-1100-1100-1101,最左位补1是
    1000-1100-1100-1100-1100-1101,结果是0011-1111-1000-1100-1100-1100-1100-1101

    对齐阶码位后尾数相加,会影响符号位
    符号位 尾数位
    0 1000-0000-0000-0000-0000-0000
    1 1000-1100-1100-1100-1100-1101
    0 0000-1100-1100-1100-1100-1101

    符号位为0 尾数为0000-1100-1100-1100-1100-1101
    规格化
    向左移动4位,阶码减4为123(1111011) 结果为
    0011-1101-1100-1100-1100-1100-1101-0000,对应十进制为0.100000024。

    总结

    上面一直讨论的是单精度,其实不管是单精度还是双精度,肯定都会出现误差,所以在不改变原来存储和表达方式的话可以改变单位来减少误差,比如用分替代元。 平时设计金额或者精度要求高的话最好用bigdecimal因为精度更高,具体我不知道是怎么存储和表达的,可能牺牲了物理存储来实现逻辑精度。

    展开全文
  • 关于浮点数的讲解

    2018-11-01 17:37:14
    数值数据在机内的表示 ... 2.1.1.1 定点数与浮点数  计算机处理的数值数据多数带有小数,小数点在计算机中通常有两种表示方法,一种是约定所有数值数据的小数点隐含在某一个固定位置上,称为定...

    数值数据在机内的表示

        在选择计算机的数值数的表示方式时,需要考虑以下几个因素:(1)要表示的数的类型(小数、整数、实数和复数);(2)可能遇到的数值范围;(3)数值精确度;(4)数据存储和处理所需要的硬件代价。

       2.1.1.1 定点数与浮点数

       计算机处理的数值数据多数带有小数,小数点在计算机中通常有两种表示方法,一种是约定所有数值数据的小数点隐含在某一个固定位置上,称为定点表示法,简称定点数;另一种是小数点位置可以浮动,称为浮点表示法,简称浮点数

    1. 定点数表示法(fixed-point)

    所谓定点格式,即约定机器中所有数据的小数点位置是固定不变的。在计算机中通常采用两种简单的约定:将小数点的位置固定在数据的最高位之前,或者是固定在最低位之后。一般常称前者为定点小数,后者为定点整数。

    定点小数是纯小数,约定的小数点位置在符号位之后、有效数值部分最高位之前。若数据 x 的形式为 x = x0.x1x2…xn ( 其中x0为符号位,x1~xn是数值的有效部分,也称为尾数, x1为最高有效位 ),则在计算机中的表示形式为:

    一般说来,如果最末位 xn = 1,前面各位都为 0 ,则数的绝对值最小,即 |x|min = 2-n 。如果各位均为 1,则数的绝对值最大,即 |x|max =1-2-n 。所以定点小数的表示范围是:

    2- n  ≤ | x | ≤ 1 -  2- n

    定点整数是纯整数,约定的小数点位置在有效数值部分最低位之后。若数据 x 的形式为 x = xx1x2…xn ( 其中x0为符号位,x1~xn 是尾数, xn 为最低有效位 ),则在计算机中的表示形式为:

        

    定点整数的表示范围是:

    1≤ | x | ≤ 2n  -  1

    当数据小于定点数能表示的最小值时,计算机将它们作0处理,称为下溢;大于定点数能表示的最大值时,计算机将无法表示,称为上溢,上溢和下溢统称为溢出

    计算机采用定点数表示时,对于既有整数又有小数的原始数据,需要设定一个比例因子,数据按其缩小成定点小数或扩大成定点整数再参加运算,运算结果,根据比例因子,还原成实际数值。若比例因子选择不当,往往会使运算结果产生溢出或降低数据的有效精度。

    用定点数进行运算处理的计算机被称为定点机。        

    2. 浮点数表示法(floating-point number)

    与科学计数法相似,任意一个J进制数N,总可以写成

    N = J E × M

    式中M称为数 N 的尾数(mantissa),是一个纯小数;E 为数 N 的阶码(exponent),是一个整数,J称为比例因子 J E 的底数。这种表示方法相当于数的小数点位置随比例因子的不同而在一定范围内可以自由浮动,所以称为浮点表示法。

    底数是事先约定好的(常取2),在计算机中不出现。在机器中表示一个浮点数时,一是要给出尾数,用定点小数形式表示。尾数部分给出有效数字的位数,因而决定了浮点数的表示精度。二是要给出阶码,用整数形式表示,阶码指明小数点在数据中的位置,因而决定了浮点数的表示范围。浮点数也要有符号位。因此一个机器浮点数应当由阶码和尾数及其符号位组成:

    其中 ES 表示阶码的符号,占一位,E1~En 为阶码值,占 n 位,尾符是数 N 的符号,也要占一位。当底数取 2 时,二进制数 N 的小数点每右移一位,阶码减小 1,相应尾数右移一位;反之,小数点每左移一位,阶码加 1,相应尾数左移一位。

    若不对浮点数的表示作出明确规定,同一个浮点数的表示就不是唯一的。例如 11.01 也可以表示成 0.011012-3 ,0.1101×2-2 等等。为了提高数据的表示精度,当尾数的值不为 0 时,其绝对值应大于等于 0.5,即尾数域的最高有效位应为 1,否则要以修改阶码同时左右移小数点的方法,使其变成这一要求的表示形式,这称为浮点数的规格化表示。

    当一个浮点数的尾数为 0 时,不论其阶码为何值,或者当阶码的值遇到比它能表示的最小值还小时,不管其尾数为何值,计算机都把该浮点数看成 0 值,称为机器零

    浮点数所表示的范围比定点数大。假设机器中的数由 8 位二进制数表示(包括符号位):在定点机中这 8 位全部用来表示有效数字(包括符号);在浮点机中若阶符、阶码占 3 位,尾符、尾数占 5 位,在此情况下,若只考虑正数值,定点机小数表示的数的范围是 0.0000000 到 0.1111111,相当于十进制数的 0 到 127/128,而浮点机所能表示的数的范围则是 2 - 11×0.0001 到 211×0.1111,相当于十进制数的 1/128到 7.5 。显然,都用 8 位,浮点机能表示的数的范围比定点机大得多。

    尽管浮点表示能扩大数据的表示范围,但浮点机在运算过程中,仍会出现溢出现象。下面以阶码占 3 位,尾数占 5 位(各包括 1 位符号位)为例,来讨论这个问题。图 2-1 给出了相应的规格化浮点数的数值表示范围。

    图2-1  规格化浮点数分布示意图

    图 2-1 中,“可表示的负数区域”和“可表示的正数区域”及“0”,是机器可表示的数据区域;上溢区是数据绝对值太大,机器无法表示的区域;下溢区是数据绝对值太小,机器无法表示的区域。若运算结果落在上溢区,就产生了溢出错误,使得结果不能被正确表示,要停止机器运行,进行溢出处理。若运算结果落在下溢区,也不能正确表示之,机器当 0 处理,称为机器零。

    一般来说,增加尾数的位数,将增加可表示区域数据点的密度,从而提高了数据的精度;增加阶码的位数,能增大可表示的数据区域。

    展开全文
  • 浮点数的表示方法

    万次阅读 多人点赞 2019-03-03 21:02:31
    把一个数的有效数字和数的范围在计算机的一个存储...其中M称为浮点数的尾数,是一个纯小数。e是比例因子的指数,称为浮点数的指数,是一个整数。比例因子的基数2对二进记数制的机器是一个常数。 在机器中表示一个...

    把一个数的有效数字和数的范围在计算机的一个存储单元中分别予以表示。这种把数的范围和精度分别表示的方法,相当于数的小数点位置随比例因子的不同而在一定范围内可以自由浮动,所以称为浮点表示法

    在计算机中一个任意二进制数N可以写成: N=2^e.M
    其中M称为浮点数的尾数,是一个纯小数。e是比例因子的指数,称为浮点数的指数,是一个整数。比例因子的基数2对二进记数制的机器是一个常数。
    在机器中表示一个浮点数时,一是要给出尾数,用定点小数形式表示。尾数部分给出有效数字的位数,因而决定了浮点数的表示精度。二是要给出指数,用整数形式表示,常称为阶码,阶码指明小数点在数据中的位置,因而决定了浮点数的表示范围。浮点数也要有符号位。

    在这里插入图片描述

    按IEEE754标准,32位浮点数和64位浮点数的标准格式为

    在这里插入图片描述
    在这里插入图片描述
    不论是32位浮点数还是64位浮点数由于基数2是固定常数,对每一个浮点数都一样,所以不必用显示方式来表示它。

    32位的浮点数中,S是浮点数的符号位,占1位,安排在最高位,S=0表示正数,S=1表示负数。M是尾数,放在低位部分,占用23位,小数点位置放在尾数域最左(最高)有效位的右边。E是阶码,占用8位,阶符采用隐含方式,,即采用移码方法来表示正负指数。移码方法对两个指数大小的比较和对阶操作都比较方便,因为阶码域值大者其指数值也大。采用这种方式时,将浮点数的指数真值e变成阶码E时,应将指数e加上一个固定的偏移值127(01111111),即E=e+127。

    为了提高数据的表示精度,当尾数的值不为0时,尾数域的最高有效位应为1,这称为浮点数的规格化表示。否则以修改阶码同时左右移动小数点位置的办法,使其变成规格化数的形式。

    在IEEE754标准中,一个规格化的32位浮点数x的真值表示为
    x = (-1) ^s X(1.M)X 2^(E-127)
    e = E - 127
    其中尾数域所表示的值是1.M。由于规格化的浮点数的尾数域最左位(最高有效位)总是1,故这一位经常不予存储,而认为隐藏在小数点的左边。于是用23位字段可以存储24位有效数。

    64位的浮点数中符号位1位,阶码域11位,尾数域52位,植树偏移值是1023.因此规格化的64位浮点数x的真值为
    x = (-1)s X(1.M)X 2^(E-1023)
    e = E - 1023

    例题
    1. 问题: 若浮点数x的754标准存储格式为(41360000)16,求其浮点数的十进制数值。
    解:将16进制数展开后,可得二进制数格式为
    在这里插入图片描述
    指数e=阶码-127=10000010-01111111=00000011=(3)10
    包括隐藏位1的尾数1.M=1.011 0110 0000 0000 0000 0000=1.011011
    于是有
    x=(-1)^S X 1.M X 2^e=+(1.011011) X 2^3 = +1011.011=(11.375)10

    2. 问题: 将数(20.59375)10转换成754标准的32位浮点数的二进制存储格式。
    解:首先分别将整数和小数部分转换成二进制数:
    20.59375 = 10100.10011
    然后移动小数点,使其在第1、2位之间
    10100.10011 = 1.010010011 X 2^4 e = 4
    于是得到
    S = 0, E = 4 + 127 = 131, M = 010010011
    最后得到32位浮点数的二进制存储格式为
    0100 0001 1010 0100 1100 0000 0000 0000 = (41A4C000)16

    展开全文
  • IEEE754 浮点数的表示方法

    万次阅读 多人点赞 2020-10-06 21:34:28
    1.浮点数的存储格式 浮点数在C/C++中对应float和double类型,我们有必要知道浮点数在计算机中实际存储的内容。 IEEE754标准中规定float单精度浮点数在机器中表示用 1 位表示数字的符号,用 8 位来表示指数,用...

    1.浮点数的存储格式

    浮点数(Floating-point Number)是对实数的一种近似表示,由一个有效数字(即尾数)加上幂数来表示,通常是乘以某个基数的整数次幂得到。以这种表示法表示的数值,称为浮点数。表示方法类似于基数为10的科学计数法。利用浮点进行运算,称为浮点计算,这种运算通常伴随着因为无法精确表示而进行的近似或舍入。

    计算机对浮点数的表示规范遵循电气和电子工程师协会(IEEE)推出的 IEEE754 标准,浮点数在 C/C++ 中对应 float 和 double 类型,我们有必要知道浮点数在计算机中实际存储的内容。

    IEEE754 标准中规定 float 单精度浮点数在机器中表示用 1 位表示数字的符号,用 8 位表示指数,用 23 位表示尾数,即小数部分。对于 double 双精度浮点数,用 1 位表示符号,用 11 位表示指数,52 位表示尾数,其中指数域称为阶码。IEEE754 浮点数的格式如下图所示。
    这里写图片描述
    注意,IEE754 规定浮点数阶码 E 采用"指数e的移码-1"来表示,请记住这一点。为什么指数移码要减去 1,这是 IEEE754 对阶码的特殊要求,以满足特殊情况,比如对正无穷的表示。

    2.移码

    移码(又叫增码)是对真值补码的符号位取反,一般用作浮点数的阶码,引入的目的是便于浮点数运算时的对阶操作。

    对于定点整数,计算机一般采用补码的来存储。正整数的符号位为 0,反码和补码等同于原码。负整数符号位为1,原码、反码和补码的表示都不相同,由原码变成反码和补码有如下规则:
    (1)原码符号位为1不变,整数的每一位二进制数位求反得反码;
    (2)反码符号位为1不变,反码数值位最低位加1得补码。

    比如,以一个字节 8bits 来表示 -3,那么[−3]原=10000011[-3]_原=10000011[3]=10000011[−3]反=11111100[-3]_反=11111100[3]=11111100[−3]补=11111101[-3]_补=11111101[3]=11111101,那么 -3 的移码就是[−3]移=01111101[-3]_移=01111101[3]=01111101

    如何将移码转换为真值 -3 呢?先将移码转换为补码,再求值。

    3.浮点数的规格化

    若不对浮点数的表示作出明确的规定,同一个浮点数的表示就不是唯一的。例如(1.75)10(1.75)_{10}(1.75)10可以表示成1.11×201.11\times 2^01.11×200.111×210.111\times2^10.111×210.0111×220.0111\times2^20.0111×22等多种形式。当尾数不为0时,尾数域的最高有效位为1,这称为浮点数的规格化。否则,以修改阶码同时左右移动小数点位置的办法,使其成为规格化数的形式。

    3.1 单精度浮点数真值

    IEEE754 标准中,一个规格化的 32 位浮点数 x 的真值表示为:
    x=(−1)S×(1.M)×2ex=(-1)^S\times(1.M)\times2^ex=(1)S×(1.M)×2e
    e=E−127e=E-127e=E127
    其中尾数域值是1.M。因为规格化的浮点数的尾数域最左位总是1,故这一位不予存储,而认为隐藏在小数点的左边。

    在计算指数 e 时,对阶码E的计算采用原码的计算方式,因此 32 位浮点数的 8bits 的阶码 E 的取值范围是 0 到 255。其中当E为全 0 或者全 1 时,是 IEEE754 规定的特殊情况,下文会另外说明。

    3.2 双精度浮点数真值

    64 位的浮点数中符号为 1 位,阶码域为 11 位,尾数域为 52 位,指数偏移值是 1023。因此规格化的 64 位浮点数 x 的真值是:
    x=(−1)S×(1.M)×2ex=(-1)^S\times(1.M)\times2^ex=(1)S×(1.M)×2e
    e=E−1023e=E-1023e=E1023

    4.浮点数的具体表示

    4.1 十进制到机器码

    (1)0.5
    0.5=(0.1)20.5=(0.1)_20.5=(0.1)2,符号位S为0,指数为e=−1e=-1e=1,规格化后尾数为1.0。

    单精度浮点数尾数域共23位,右侧以0补全,尾数域:
    M=[000 0000 0000 0000 0000 0000]2M=[000\ 0000\ 0000\ 0000\ 0000\ 0000]_2M=[000 0000 0000 0000 0000 0000]2

    阶码E:
    E=[−1]移−1=[0111 1111]2−1=[0111 1110]2E=[-1]_移-1=[0111\ 1111]_2-1=[0111\ 1110]_2E=[1]1=[0111 1111]21=[0111 1110]2

    对照单精度浮点数的存储格式,将符号位S,阶码E和尾数域M存放到指定位置,得0.5的机器码:
    0.5=[0011 1111 0000 0000 0000 0000 0000 0000]20.5=[0011\ 1111\ 0000\ 0000\ 0000\ 0000\ 0000\ 0000]_20.5=[0011 1111 0000 0000 0000 0000 0000 0000]2

    十六进制表示为0.5=0x3f000000。

    (2)1.5
    1.5=[1.1]21.5=[1.1]_21.5=[1.1]2,符号位为0,指数e=0e=0e=0,规格化后尾数为1.1。

    尾数域M右侧以0补全,得尾数域:
    M=[100 0000 0000 0000 0000 0000]2M=[100\ 0000\ 0000\ 0000\ 0000\ 0000]_2M=[100 0000 0000 0000 0000 0000]2

    阶码E:
    E=[0]移−1=[10000000]2−1=[01111111]2E=[0]_移-1=[1000 0000]_2-1=[0111 1111]_2E=[]1=[10000000]21=[01111111]2

    得1.5的机器码:
    1.5=[0011 1111 1100 0000 0000 0000 0000 0000]21.5=[0011\ 1111\ 1100\ 0000\ 0000\ 0000\ 0000\ 0000]_21.5=[0011 1111 1100 0000 0000 0000 0000 0000]2

    十六进制表示为1.5=0x3fc00000。

    (3)-12.5
    −12.5=[−1100.1]2-12.5=[-1100.1]_212.5=[1100.1]2,符号位S为1,指数e为3,规格化后尾数为1.1001,

    尾数域M右侧以0补全,得尾数域:
    M=[100 1000 0000 0000 0000 0000]2M=[100\ 1000\ 0000\ 0000\ 0000\ 0000]_2M=[100 1000 0000 0000 0000 0000]2

    阶码E:
    E=[3]移−1=[1000 0011]2−1=[1000 0010]2E=[3]_移-1=[1000\ 0011]_2-1=[1000\ 0010]_2E=[3]1=[1000 0011]21=[1000 0010]2

    即-12.5的机器码:
    −12.5=[1100 0001 0100 1000 0000 0000 0000 0000]2-12.5=[1100\ 0001\ 0100\ 1000\ 0000\ 0000\ 0000\ 0000]_212.5=[1100 0001 0100 1000 0000 0000 0000 0000]2

    十六进制表示为-12.5=0xc1480000。

    用如下程序验证上面的推算,代码编译运行平台Win32+VC++ 2012:

    #include <iostream>
    using namespace std;
    
    int main() {
    	float a=0.5;
    	float b=1.5;
    	float c=-12.5;
    
    	unsigned int* pa=NULL;
    	pa=(unsigned int*)&a;
    	unsigned int* pb=NULL;
    	pb=(unsigned int*)&b;
    	unsigned int* pc=NULL;
    	pc=(unsigned int*)&c;
    	
    	cout<<hex<<"a=0x"<<*pa<<endl;
    	cout<<hex<<"b=0x"<<*pb<<endl;
    	cout<<hex<<"c=0x"<<*pc<<endl;
    	
    	return 0;
    }
    

    输出结果:

    a=0x3f000000
    b=0x3fc00000
    c=0xc1480000
    

    验证正确。

    4.2 机器码到十进制

    (1)若浮点数 x 的 IEEE754 标准存储格式为 0x41360000,那么其浮点数的十进制数值的推演过程如下:

    0x41360000=[0 10000010 011 0110 0000 0000 0000 0000]0x41360000=[0\ 10000010\ 011\ 0110\ 0000\ 0000\ 0000\ 0000]0x41360000=[0 10000010 011 0110 0000 0000 0000 0000]

    根据该浮点数的机器码得到符号位 S=0,指数 e=阶码-127=1000 0010-127=130-127=3

    注意,根据阶码求指数时,可以像上面直接通过 "阶码-127"求得指数e,也可以将阶码+1=移码阶码+1=移码+1=,再通过移码求其真值便是指数 e。比如上面阶码 10000010+1=10000011[移码]=>00000011[补]=3(指数e)10000010+1=10000011_{[移码]}=>00000011_{[补]}=3(指数e)10000010+1=10000011[]=>00000011[]=3(e)

    包括尾数域最左边的隐藏位1,那么尾数 1.M=1.011 0110 0000 0000 0000 0000=1.011011。

    于是有:
    x=(−1)S×1.M×2e=+(1.011011)×23=+1011.011=(11.375)10x=(-1)^S\times1.M\times2^e=+(1.011011)\times2^3=+1011.011=(11.375)_{10}x=(1)S×1.M×2e=+(1.011011)×23=+1011.011=(11.375)10

    通过代码同样可以验证上面的推算:

    #include <iostream>
    using namespace std;
    
    int main() {
    	unsigned int hex=0x41360000;
    	float* fp=(float*)&hex;
    	cout<<"x="<<*fp<<endl;
    	return 0;
    }
    

    输出结果:

    x=11.375
    

    验证正确。

    5.浮点数的几种特殊情况

    (1)0 的表示
    对于阶码为 0 或 255 的情况,IEEE754 标准有特别的规定:
    如果 阶码 E=0 并且尾数 M 是 0,则这个数的真值为 ±0(正负号和数符位有关)。

    因此 +0 的机器码为:0 00000000 000 0000 0000 0000 0000 0000。
    -0 的机器码为:1 00000000 000 0000 0000 0000 0000 0000。

    需要注意一点,浮点数不能精确表示 0,而是以很小的数来近似表示 0,因为浮点数的真值等于(以32bits单精度浮点数为例):
    x=(−1)S×(1.M)×2ex=(-1)^S\times(1.M)\times2^ex=(1)S×(1.M)×2e
    e=E−127e=E-127e=E127
    那么 +0 的机器码对应的真值为1.0×2−1271.0\times2^{-127}1.0×2127。同理,-0 机器码真值为−1.0×2−127-1.0\times2^{-127}1.0×2127

    (2)+∞+\infty+−∞-\infty 的表示
    如果阶码 E=255 并且尾数 M 全是0,则这个数的真值为 ±∞(同样和符号位有关)。因此+∞+\infty+的机器码为:0 11111111 000 0000 0000 0000 0000 0000。−∞-\infty的机器吗为:1 11111111 000 0000 0000 0000 0000 0000。

    (3)NaN(Not a Number)
    如果 E = 255 并且 M 不是0,则这不是一个数(NaN)。

    6.浮点数的精度和数值范围

    6.1 浮点数的数值范围

    根据上面的探讨,浮点数可以表示-∞到+∞,这只是一种特殊情况,显然不是我们想要的数值范围。

    以 32 位单精度浮点数为例,阶码 E 由 8 位表示,取值范围为 0-255,去除 0 和 255 这两种特殊情况,那么指数 e 的取值范围就是 1-127=-126 到 254-127=127。

    (1)最大正数
    因此单精度浮点数最大正数值的符号位S=0,阶码E=254,指数e=254-127=127,尾数M=111 1111 1111 1111 1111 1111,其机器码为:0 11111110 111 1111 1111 1111 1111 1111。

    那么最大正数值:
    PosMax=(−1)S×1.M×2e=+(1.11111111111111111111111)×2127≈3.402823e+38PosMax=(-1)^S\times1.M\times2^e=+(1.111 1111 1111 1111 1111 1111)\times2^{127}\approx3.402823e+38PosMax=(1)S×1.M×2e=+(1.11111111111111111111111)×21273.402823e+38
    这是一个很大的数。

    (2)最小正数
    最小正数符号位S=0,阶码E=1,指数e=1-127=-126,尾数M=0,其机器码为0 00000001 000 0000 0000 0000 0000 0000。

    那么最小正数为:
    PosMin=(−1)S×1.M×2e=+(1.0)×2−126≈1.175494e−38PosMin=(-1)^S\times1.M\times2^e=+(1.0)\times2^{-126} \approx1.175494e-38PosMin=(1)S×1.M×2e=+(1.0)×21261.175494e38

    这是一个相当小的数。几乎可以近似等于0。当阶码E=0,指数为-127时,IEEE754就是这么规定1.0×2−1271.0\times2^{-127}1.0×2127近似为0的,事实上,它并不等于0。

    (3)最大负数
    最大负数符号位S=1,阶码E=1,指数e=1-127==-126,尾数M=0,机器码与最小正数的符号位相反,其他均相同,为:1 00000001 000 0000 0000 0000 0000 0000。

    最大负数等于:
    NegMax=(−1)S×1.M×2e=−(1.0)×2−126≈−1.175494e−38NegMax=(-1)^S\times1.M\times2^e=-(1.0)\times2^{-126} \approx-1.175494e-38NegMax=(1)S×1.M×2e=(1.0)×21261.175494e38

    (4)最小负数
    符号位S=0,阶码E=254,指数e=254-127=127,尾数M=111 1111 1111 1111 1111 1111,其机器码为:1 11111110 111 1111 1111 1111 1111 1111。

    计算得:
    NegMin=(−1)S×1.M×2e=+(1.11111111111111111111111)×2127=−3.402823e+38NegMin=(-1)^S\times1.M\times2^e=+(1.111 1111 1111 1111 1111 1111)\times2^{127}=-3.402823e+38NegMin=(1)S×1.M×2e=+(1.11111111111111111111111)×2127=3.402823e+38

    6.2 浮点数的精度

    说到浮点数的精度,先给精度下一个定义。浮点数的精度是指浮点数的小数位所能表达的位数。

    阶码的二进制位数决定浮点数的表示范围,尾数的二进制位数表示浮点数的精度。以 32 位浮点数为例,尾数域有 23 位。那么浮点数以二进制表示的话精度是 23 位,23 位所能表示的最大数是223−1=83886072^{23}-1=83886072231=8388607,所以十进制的尾数部分最大数值是 8388607,也就是说尾数数值超过这个值,float 将无法精确表示,所以 float 最多能表示小数点后 7 位,但绝对能保证的为 6 位,即 float 的十进制的精度为 6~7 位。

    64 位双精度浮点数的尾数域 52 位,因252−1=4,503,599,627,370,4952^{52}-1=4,503,599,627,370,4952521=4,503,599,627,370,495,所以双精度浮点数的十进制的精度最高为 16 位,绝对保证的为 15 位,所以 double 的十进制的精度为 15~16 位。

    7.小结

    本文操之过急,难免出现编辑错误和不当说法,请网友批评指正。不明之处,欢迎留言交流。对浮点数的加减乘除运算还未涉及,后续可能会去学习并记录学习所得,与大家分享。


    参考文献

    [1] 百度百科.移码
    [2] 百度知道.关于IEEE754标准浮点数阶码的移码
    [3] 白中英.计算机组成原理第四版[M].科学出版社:P16-30
    [4] 维基百科.浮点数

    展开全文
  • 浮点数运算原理详解

    万次阅读 2020-02-28 20:06:40
    导读:浮点数运算是一个非常有技术含量的话题,不太容易掌握。许多程序员都不清楚使用==操作符比较float/double类型的话到底出现什么问题。 许多人使用float/double进行货币计算时经常会犯错。这篇文章是这一系列中...
  • 计算机组成原理之浮点数

    千次阅读 2018-11-08 18:26:39
    一、浮点数的表示方法: 在计算机中,一个任意进制数N可以可以写成:N=R^e*M 一般来说,变化的数值是M和e。在计算机中只需要存M和e即可,R默认为2。为了使浮点数的表示具有唯一性,需要在运算过程中对浮点数进行...
  • [C]浮点数详解

    2019-07-02 18:40:10
    IEEE 754规定任意一个二进制浮点数V可以表示成下面的形式: V=(−1)S×M×2EV=(-1)^S × M × 2^EV=(−1)S×M×2E 例如下图是32位单精度浮点数存储模型 其中S表示符号位,当S=0,V为正数;当S=1,V为负数。 ​M表示...
  • 4. 乘除运算及浮点数运算

    千次阅读 2018-12-01 20:14:27
    4.1 整数乘法运算 1. 整数乘法 通常,高级语言中两个n位整数相乘得到的结果通常也是一个n位整数,即结果只取2n位乘积中的低n位。 –例如,在C语言中,参加运算的两个操作数的... 如x是浮点数,则一定! 例如,当...
  • C语言浮点数

    千次阅读 2019-04-13 19:56:06
    C语言规定了3种浮点数,float型、double型和long double型,其中float型占4个字节,double型占8个字节,longdouble型长度要大于等于double型,本文档将以float型为例进行介绍,double型和long double型只是比float型...
  • 浮点数大小比较

    千次阅读 2019-04-25 22:56:21
    在一次某公司的笔试题中出现了一题在一个无序的浮点数数组中找出相同的数,那么在计算机中一般的整型的十进制数一般都是直接通过“==”来判断两个数是否相等的,但是如果是浮点数还可以用这样的方式进行判断吗?...
  • 解读IEEE标准754:浮点数的表示

    万次阅读 2018-10-31 16:29:28
    在IEEE标准754之前,业界并没有一个统一的浮点数标准,相反,很多计算机制造商都设计自己的浮点数规则,以及运算细节。那时,实现的速度和简易性比数字的精确性更受重视。  直到1985年Intel打算为其的8086微处理器...
  • 浮点数详解

    千次阅读 2020-01-07 20:13:48
    所谓“浮点”是什么意思呢? 计算机能处理二进制的数,那么小数是怎么处理的呢?下面一起来看看 ~~ “浮点”的“点”指的是小数点,而“浮”指的是小数点的移动 小数的处理其实类似于科学计数法 ...
  • 程序员必知之浮点数运算原理详解

    万次阅读 多人点赞 2018-05-08 10:40:52
    导读:浮点数运算是一个非常有技术含量的话题,不太容易掌握。许多程序员都不清楚使用==操作符比较float/double类型的话到底出现什么问题。 许多人使用float/double进行货币计算时经常会犯错。这篇文章是这一系列中...
  • 浮点数表示

    万次阅读 多人点赞 2016-12-23 09:22:23
    之前的一些工作当中碰到了很多有关浮点数的问题,比如浮点数的表达范围、表达精度、浮点数的存储方式、浮点数的强制类型转换等等,因此感觉有必要系统了解一下有关浮点数的问题。 —————————— 浮点数表示 ...
  • 单精度浮点数(float)与双精度浮点数(double)的区别如下:(1)在内存中占有的字节数不同单精度浮点数在机内占4个字节双精度浮点数在机内占8个字节(2)有效数字位数不同单精度浮点数有效数字8位双精度浮点数有效...
  • 乘除运算及浮点数运算

    千次阅读 2017-02-22 23:55:12
    整数乘法运算 整数除法运算 浮点加减运算 浮点运算的精度 浮点运算精度举例
  • IEEE标准中32位、64位浮点数的取值范围

    万次阅读 多人点赞 2019-03-14 14:01:03
    IEEE标准下,浮点数的取值范围
  • 04:输出保留3位小数的浮点数

    万次阅读 2017-03-07 21:56:33
    读入一个单精度浮点数,保留3位小数输出这个浮点数。输入 只有一行,一个单精度浮点数。 输出 也只有一行,读入的单精度浮点数。 样例输入 12.34521 样例输出 12.345 来源 习题(2-2)源代码如下:#include #...
  • 在一行中按照字符、整数、浮点数1、浮点数2的顺序输出,其中浮点数保留小数点后2位。 输入样例: 2.12 88 c 4.7 输出样例: c 88 2.12 4.70 # include <stdio.h> int main(void) { float f1, f2; ...
  • 32位单精度浮点数表示法

    万次阅读 2017-12-19 16:28:56
    32位单精度浮点数表示法
1 2 3 4 5 ... 20
收藏数 323,942
精华内容 129,576
关键字:

浮点数