浮点数的表示和基本运算
1 浮点数的表示
通常,我们可以用下面的格式来表示浮点数
S P M
其中S是符号位,P是阶码,M是尾数
对于IBM-PC而言,单精度浮点数是32位(即4字节)的,双精度浮点数是64位(即8字节)的。两者的S,P,M所占的位数以及表示方法由下表可知
S P M 表示公式 偏移量
1 8 23 (-1)S*2(P-127)*1.M 127
1 11 52 (-1)S*2(P-1023)*1.M 1023
以单精度浮点数为例,可以得到其二进制的表示格式如下
S(第31位) P(30位到23位) M(22位到0位)
其中S是符号位,只有0和1,分别表示正负;P是阶码,通常使用移码表示(移码和补码只有符号位相反,其余都一样。对于正数而言,原码,反码和补码都一样;对于负数而言,补码就是其绝对值的原码全部取反,然后加1.)
为了简单起见,本文都只讨论单精度浮点数,双精度浮点数也是用一样的方式存储和表示的。
2 浮点数的表示约定
单精度浮点数和双精度浮点数都是用IEEE754标准定义的,其中有一些特殊约定。
(1) 当P = 0, M = 0时,表示0。
(2) 当P = 255, M = 0时,表示无穷大,用符号位来确定是正无穷大还是负无穷大。
(3) 当P = 255, M != 0时,表示NaN(Not a Number,不是一个数)。
当我们使用.Net Framework的时候,我们通常会用到下面三个常量
Console.WriteLine(float.MaxValue); // 3.402823E+38
Console.WriteLine(float.MinValue); //-3.402823E+38
Console.WriteLine(float.Epsilon); // 1.401298E-45
//如果我们把它们转换成双精度类型,它们的值如下
Console.WriteLine(Convert.ToDouble(float.MaxValue)); // 3.40282346638529E+38
Console.WriteLine(Convert.ToDouble(float.MinValue)); //-3.40282346638529E+38
Console.WriteLine(Convert.ToDouble(float.Epsilon)); // 1.40129846432482E-45
那么这些值是如何求出来的呢?
根据上面的约定,我们可以知道阶码P的最大值是11111110(这个值是254,因为255用于特殊的约定,那么对于可以精确表示的数来说,254就是最大的阶码了)。尾数的最大值是11111111111111111111111。
那么这个最大值就是:0 11111110 11111111111111111111111。
也就是 2(254-127) * (1.11111111111111111111111)2 = 2127 * (1+1-2-23) = 3.40282346638529E+38
从上面的双精度表示可以看出,两者是一致的。最小的数自然就是-3.40282346638529E+38。
对于最接近于0的数,根据IEEE754的约定,为了扩大对0值附近数据的表示能力,取阶码P = -126,尾数 M = (0.00000000000000000000001)2 。此时该数的二进制表示为:0 00000000 00000000000000000000001
也就是2-126 * 2-23 = 2-149 = 1.40129846432482E-45。这个数字和上面的Epsilon是一致的。
如果我们要精确表示最接近于0的数字,它应该是 0 00000001 00000000000000000000000
也就是:2-126 * (1+0) = 1.17549435082229E-38。
3 浮点数的精度问题
浮点数以有限的32bit长度来反映无限的实数集合,因此大多数情况下都是一个近似值。同时,对于浮点数的运算还同时伴有误差扩散现象。特定精度下看似相等的两个浮点数可能并不相等,因为它们的最小有效位数不同。
由于浮点数可能无法精确近似于十进制数,如果使用十进制数,则使用浮点数的数学或比较运算可能不会产生相同的结果。
如果涉及浮点数,值可能不往返。值的往返是指,某个运算将原始浮点数转换为另一种格式,而反向运算又将转换后的格式转换回浮点数,且最终浮点数与原始浮点数相等。由于一个或多个最低有效位可能在转换中丢失或更改,往返可能会失败。
4 将浮点数表示为二进制
4.1 无小数的浮点数转换成二进制表示
首先,我们用一个不带小数的浮点数来说明如何将一个浮点数转换成二进制表示。假设要转换的数据是45678.0f。
在处理这种不带小数的浮点数时,直接将整数部分转化为二进制表示:
1011001001101110.0,这时要加上一位默认的1(这是因为按照浮点数规格化的要求,尾数必须化成 1.M的格式),
那么可以表示成:11011001001101110.0。
然后将小数点向左移,一直移到离最高位只有1位,也就是 1.1011001001101110,一共移动了16位,我们知道,左移位表示乘法,右移位表示除法。所以原数就等于这样:1.1011001001101110 * ( 216 )。现在尾数和指数都出来了。因为最高位的1是根据标准加上去的,只是为了满足规格化的要求,这时候需要把这个1去掉。尾数的二进制就变成了:1011001001101110。
最后在尾数的后面补0,一直到补够23位,就是:10110010011011100000000。
再回来看指数,根据前面的定义,P-127=16,那么P = 143,表示成二进制就是:10001111。
45678.0f这个数是正的,所以符号位是0,那么我们按照前面讲的格式把它拼起来,就是:0 10001111 10110010011011100000000。
这就是45678.0f这个数的二进制表示,如果我们要得到16进制的表示,非常简单,我们只需要把这个二进制串4个一组,转换成16进制数就可以了。但是要注意的是x86架构的CPU都是Little Endian的(也就是低位字节在前,高位字节在后),所以在实际内存中该数字是按上面二进制串的倒序存储的。要知道CPU是不是little endian的也很容易。
BitConverter.IsLittleEndian;
4.2 含小数的浮点数表示为二进制
对于含小数的浮点数,会有精度的问题,下面举例说明。假设要转换的小数为123.456f。
对于这种带小数的就需要把整数部和小数部分开处理。对于整数部分的处理不再赘述,直接化成二进制为:100100011。小数部份的处理比较麻烦一些,我们知道,使用二进制表示只有0和1,那么对于小数就只能用下面的方式来表示:
a1*2-1+a2*2-2+a3*2-3+......+an*2-n
其中a1等数可以是0或者1,从理论上将,使用这种表示方法可以表示一个有限的小数。但是尾数只能有23位,那么就必然会带来精度的问题。
在很多情况下,我们只能近似地表示小数。来看0.456这个十进制纯小数,该如何表示成二进制呢?一般说来,我们可以通过乘以2的方法来表示。
首先,把这个数字乘以2,小于1,所以第一位为0,然后再乘以2,大于1,所以第二位为1,将这个数字减去1,再乘以2,这样循环下去,直到这个数字等于0为止。
在很多情况下,我们得到的二进制数字都大于23位,多于23位的就要舍去。舍入原则是0舍1入。通过这样的办法,我们可以得到二进制表示:1111011.01110100101111001。
现在开始向左移小数点,一共移了6位,这时候尾数为:1.11101101110100101111001,阶码为6加上127得131,二进制表示为:10000101,那么总的二进制表示为:
0 10000101 11101101110100101111001
表示成十六进制是:42 F6 E9 79
由于CPU是Little Endian的,所以在内存中表示为:79 E9 F6 42。
4.3 将纯小数表示成二进制
对于纯小数转化为二进制来说,必须先进行规格化。例如0.0456,我们需要把它规格化,变为1.xxxx * (2n )的形式,要求得纯小数X对应的n可用下面的公式:
n = int( 1 + log 2X )
0.0456我们可以表示为1.4592乘以以2为底的-5次方的幂,即1.4592 * ( 2-5 )。转化为这样形式后,再按照上面处理小数的方法处理,得到二进制表示
1. 01110101100011100010001
去掉第一个1,得到尾数
01110101100011100010001
阶码为:-5 + 127 = 122,二进制表示为
0 01111010 01110101100011100010001
最后转换成十六进制
11 C7 3A 3D
5 浮点数的数学运算
5.1 浮点数的加减法
设两个浮点数 X=Mx*2Ex ,Y=My*2Ey
实现X±Y要用如下5步完成:
(1)对阶操作:小阶向大阶看齐
(2)进行尾数加减运算
(3)规格化处理:尾数进行运算的结果必须变成规格化的浮点数,对于双符号位(就是使用00表示正数,11表示负数,01表示上溢出,10表示下溢出)的补码尾数来说,就必须是
001×××…×× 或110×××…××的形式
若不符合上述形式要进行左规或右规处理。
(4)舍入操作:在执行对阶或右规操作时常用“0”舍“1”入法将右移出去的尾数数值进行舍入,以确保精度。
(5)判结果的正确性:即检查阶码是否溢出
若阶码下溢(移码表示是00…0),要置结果为机器0;
若阶码上溢(超过了阶码表示的最大值)置溢出标志。
现在用一个具体的例子来说明上面的5个步骤
例题:假定X=0 .0110011*211,Y=0.1101101*2-10(此处的数均为二进制), 计算X+Y;
首先,我们要把这两个数变成2进制表示,对于浮点数来说,阶码通常用移码表示,而尾数通常用补码表示。
要注意的是-10的移码是00110
[X]浮: 0 1 010 1100110
[Y]浮: 0 0 110 1101101
符号位 阶码 尾数
(1)求阶差:│ΔE│=|1010-0110|=0100
(2)对阶:Y的阶码小,Y的尾数右移4位
[Y]浮变为 0 1 010 0000110 1101暂时保存
(3)尾数相加,采用双符号位的补码运算
00 1100110
+00 0000110
00 1101100
(4)规格化:满足规格化要求
(5)舍入处理,采用0舍1入法处理
故最终运算结果的浮点数格式为: 0 1 010 1101101
即X+Y=+0. 1101101*210
5.2 浮点数的乘除法
(1)阶码运算:阶码求和(乘法)或阶码求差(除法)
即 [Ex+Ey]移= [Ex]移+ [Ey]补
[Ex-Ey]移= [Ex]移+ [-Ey]补
(2)浮点数的尾数处理:浮点数中尾数乘除法运算结果要进行舍入处理
例题:X=0 .0110011*211,Y=0.1101101*2-10 求X*Y
解:[X]浮: 0 1 010 1100110
[Y]浮: 0 0 110 1101101
(1)阶码相加
[Ex+Ey]移=[Ex]移+[Ey]补=1 010+1 110=1 000
1 000为移码表示的0
(2)原码尾数相乘的结果为:
0 10101101101110
(3)规格化处理:已满足规格化要求,不需左规,尾数不变,阶码不变。
(4)舍入处理:按舍入规则,加1进行修正
所以 X※Y= 0.1010111*20
分享到:
相关推荐
浮点数的运算包括加法、减法、乘法、除法等基本运算,以及一些特殊的运算,如平方根、指数运算等。 本PPT课件对浮点数的表示和运算进行了详细的介绍,对计算机科学的学生和从业人员非常有帮助。
浮点数表示和运算是计算机组成原理的重要内容之一,本文将对浮点数表示和运算进行详细的介绍。 一、浮点数表示 浮点数是计算机中的一种数制表示方法,它可以表示很大的数值范围。浮点数由三个部分组成:符号位、阶...
浮点数的运算包括加、减、乘、除等基本运算,然后是更复杂的运算,如平方根、指数函数等。浮点数的运算需要遵守一定的规则和规范,以确保运算结果的正确性和可靠性。 浮点数的应用非常广泛,例如在科学计算、工程...
浮点数运算包括加法、减法、乘法和除法等基本操作,但与整数运算不同,浮点数运算涉及到更复杂的数学原理和计算机内部表示。 浮点数在计算机中的存储方式遵循IEEE 754标准,该标准定义了单精度(32位)和双精度(64...
在当前提供的文档内容中,我们可以看到文档主要描述了浮点数运算的定义和过程,包括加法、减法、乘法和除法四种基本运算。浮点数运算是一种在计算机科学中广泛使用的数值计算方式,它能够表示非常大或者非常小的数值...
C#浮点数的表示和基本运算 浮点数是计算机科学中一种常用的数值表示方法,它可以表示非常大的数字范围,以满足科学计算、工程计算和其他领域的需求。在C#中,浮点数的表示和基本运算是非常重要的知识点,本文将对其...
通过这个课设,学生将深入理解二进制逻辑运算、定点和浮点数的算术运算,这些都是计算机硬件和软件设计的基础。完成这样的任务有助于提高编程技巧,增强对计算机底层运作的理解,对未来的编程和系统设计工作有着重要...
浮点数由阶码(表示指数)和尾数(表示小数部分)组成,通常采用IEEE 754标准。在加减运算中,需要对齐尾数的小数点,处理阶码的差异,并考虑下溢(underflow)和上溢(overflow)。下溢发生在两个非常接近的负数...
7. **组合浮点数**:最后,将符号位、指数和尾数组合成完整的浮点数表示。 对于其他子程序,如`fadd`, `fsub`, `fmul`, 和 `fdiv`,每个运算都需要考虑浮点数的表示方式,并且可能涉及到溢出和下溢的问题。在实现...
在计算机科学中,高精度浮点数运算是一种处理超越普通浮点类型(如double和long double)精度需求的计算方式。这些类型的浮点数虽然在大多数应用中已经足够精确,但在金融、科学计算或者数学算法等领域,更高精度的...
在ASM环境下调用这些子程序可以极大地简化编程,因为程序员不需要直接处理浮点数的二进制表示和运算细节。例如,一个简单的浮点数加法子程序可能如下所示: ```asm section .text global add_float add_float: ; ...
本课程设计报告通过实际编程实现这些基本运算,旨在让学生掌握计算机内部数据表示和计算的方法,了解计算机硬件如何执行算术逻辑操作,为后续学习操作系统、编译原理等高级课程打下坚实的基础。同时,这样的实践也有...
1. **浮点数表示**:在计算机内部,浮点数通常采用IEEE 754标准来表示。该标准定义了单精度(32位)和双精度(64位)浮点数的存储格式。 2. **浮点数除法**:浮点数的除法涉及到指数部分和尾数部分的处理。指数部分...
尽管定点运算不涉及浮点数的动态范围调整,但理解和掌握定点运算有助于理解浮点运算的基本原理。 在实际应用中,浮点运算速度、精度和稳定性都是需要考虑的重要因素。不同的硬件平台对浮点运算的支持程度不同,可能...
MATLAB提供了丰富的函数和运算符来处理浮点数,使得浮点数运算变得高效且直观。下面将详细解释MATLAB中浮点数的运算原理、常见运算符和相关知识点。 1. **浮点数的表示**: MATLAB使用双精度浮点数(double ...
例如,`DecimalConvertUtils.java`可能就是一个用于转换和操作`BigDecimal`的工具类,可能包含了将基本类型的浮点数转换为`BigDecimal`,以及进行加减乘除、取模等运算的方法。 `BigDecimal`类提供了丰富的API,如`...
数据表示、运算和运算器部件 数据表示是计算机科学中的一种基本概念,指的是将信息转换为计算机可以理解和处理的形式。在计算机内部,所有信息都需要用数字化编码的形式被存储、加工和传送。数字化编码的基本要素是...
浮点数表示法通过灵活的小数点位置和分段表示的方式,极大地扩展了计算机处理实数的能力。IEEE 754标准的提出进一步规范了浮点数的表示和运算,提高了数值计算的准确性和效率。规格化浮点数和相关的操作规则则是实现...