企业做网站需要注意什么,申请域名 建设网站,网站查备案密码,wordpress contactform1 浮点数的表示通常#xff0c;我们可以用下面的格式来表示浮点数 SPM其中S是符号位#xff0c;P是阶码#xff0c;M是尾数对于IBM-PC而言#xff0c;单精度浮点数是32位#xff08;即4字节#xff09;的#xff0c;双精度浮点数是64位#xff08;即8字节#xff09;的…1 浮点数的表示通常我们可以用下面的格式来表示浮点数 SPM其中S是符号位P是阶码M是尾数对于IBM-PC而言单精度浮点数是32位即4字节的双精度浮点数是64位即8字节的。两者的SPM所占的位数以及表示方法由下表可知 SPM表示公式偏移量1823(-1)S*2(P-127)*1.M12711152(-1)S*2(P-1023)*1.M1023以单精度浮点数为例可以得到其二进制的表示格式如下 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时表示NaNNot a Number不是一个数。当我们使用.Net Framework的时候我们通常会用到下面三个常量 Console.WriteLine(float.MaxValue); //3.402823E38Console.WriteLine(float.MinValue); //-3.402823E38Console.WriteLine(float.Epsilon); //1.401298E-45//如果我们把它们转换成双精度类型它们的值如下Console.WriteLine(Convert.ToDouble(float.MaxValue)); //3.40282346638529E38Console.WriteLine(Convert.ToDouble(float.MinValue)); //-3.40282346638529E38Console.WriteLine(Convert.ToDouble(float.Epsilon)); //1.40129846432482E-45 那么这些值是如何求出来的呢根据上面的约定我们可以知道阶码P的最大值是11111110这个值是254因为255用于特殊的约定那么对于可以精确表示的数来说254就是最大的阶码了。尾数的最大值是11111111111111111111111。那么这个最大值就是0 11111110 11111111111111111111111。也就是 2(254-127) * (1.11111111111111111111111)2 2127 * (11-2-23) 3.40282346638529E38从上面的双精度表示可以看出两者是一致的。最小的数自然就是-3.40282346638529E38。对于最接近于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 * (10) 1.17549435082229E-38。 3 浮点数的精度问题浮点数以有限的32bit长度来反映无限的实数集合因此大多数情况下都是一个近似值。同时对于浮点数的运算还同时伴有误差扩散现象。特定精度下看似相等的两个浮点数可能并不相等因为它们的最小有效位数不同。 由于浮点数可能无法精确近似于十进制数如果使用十进制数则使用浮点数的数学或比较运算可能不会产生相同的结果。 如果涉及浮点数值可能不往返。值的往返是指某个运算将原始浮点数转换为另一种格式而反向运算又将转换后的格式转换回浮点数且最终浮点数与原始浮点数相等。由于一个或多个最低有效位可能在转换中丢失或更改往返可能会失败。 4 将浮点数表示为二进制4.1 无小数的浮点数转换成二进制表示首先我们用一个不带小数的浮点数来说明如何将一个浮点数转换成二进制表示。假设要转换的数据是45678.0f。在处理这种不带小数的浮点数时直接将整数部分转化为二进制表示1011001001101110.0然后将小数点向左移一直移到离最高位只有1位也就是 1.011001001101110一共移动了15位我们知道左移位表示乘法右移位表示除法。所以原数就等于这样1.011001001101110 * ( 215 )。现在尾数和指数都出来了。尾数的二进制就变成了011001001101110。最后在尾数的后面补0一直到补够23位就是011001001101110000000000。再回来看指数根据前面的定义P-12715那么P 142表示成二进制就是10001110。45678.0f这个数是正的所以符号位是0那么我们按照前面讲的格式把它拼起来就是0 10001110 01100100110111000000000。这就是45678.0f这个数的二进制表示如果我们要得到16进制的表示非常简单我们只需要把这个二进制串4个一组转换成16进制数就可以了。但是要注意的是x86架构的CPU都是Little Endian的也就是低位字节在前高位字节在后所以在实际内存中该数字是按上面二进制串的倒序存储的。要知道CPU是不是little endian的也很容易。 4.2 含小数的浮点数表示为二进制对于含小数的浮点数会有精度的问题下面举例说明。假设要转换的小数为123.456f。对于这种带小数的就需要把整数部和小数部分开处理。对于整数部分的处理不再赘述直接化成二进制为1111011。小数部份的处理比较麻烦一些我们知道使用二进制表示只有0和1那么对于小数就只能用下面的方式来表示a1*2-1a2*2-2a3*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 3D5 浮点数的数学运算5.1 浮点数的加减法设两个浮点数 XMx*2Ex YMy*2Ey实现X±Y要用如下5步完成1对阶操作小阶向大阶看齐2进行尾数加减运算3规格化处理尾数进行运算的结果必须变成规格化的浮点数对于双符号位就是使用00表示正数11表示负数01表示上溢出10表示下溢出的补码尾数来说就必须是001×××…×× 或110×××…××的形式若不符合上述形式要进行左规或右规处理。4舍入操作在执行对阶或右规操作时常用“0”舍“1”入法将右移出去的尾数数值进行舍入以确保精度。5判结果的正确性即检查阶码是否溢出若阶码下溢移码表示是00…0要置结果为机器0若阶码上溢超过了阶码表示的最大值置溢出标志。现在用一个具体的例子来说明上面的5个步骤例题假定X0 .0110011*211Y0.1101101*2-10此处的数均为二进制 计算XY首先我们要把这两个数变成2进制表示对于浮点数来说阶码通常用移码表示而尾数通常用补码表示。要注意的是-10的移码是00110 [X]浮 0 1 010 1100110 [Y]浮 0 0 110 1101101 符号位 阶码 尾数1求阶差│ΔE│|1010-0110|01002对阶Y的阶码小Y的尾数右移4位 [Y]浮变为 0 1 010 0000110 1101暂时保存 3尾数相加采用双符号位的补码运算 00 1100110 00 0000110 00 11011004规格化满足规格化要求 5舍入处理采用0舍1入法处理故最终运算结果的浮点数格式为 0 1 010 1101101即XY0. 1101101*210 5.2 浮点数的乘除法1阶码运算阶码求和乘法或阶码求差除法 即 [ExEy]移 [Ex]移 [Ey]补 [Ex-Ey]移 [Ex]移 [-Ey]补2浮点数的尾数处理浮点数中尾数乘除法运算结果要进行舍入处理例题X0 .0110011*211Y0.1101101*2-10 求X*Y解[X]浮 0 1 010 1100110 [Y]浮 0 0 110 11011011阶码相加 [ExEy]移[Ex]移[Ey]补1 0101 1101 000 1 000为移码表示的02原码尾数相乘的结果为0 101011011011103规格化处理已满足规格化要求不需左规尾数不变阶码不变。4舍入处理按舍入规则加1进行修正所以 X※Y 0.1010111*20 原文链接http://www.cnblogs.com/FlyingBread/archive/2009/02/15/660206.html转载于:https://www.cnblogs.com/xiaojiaohuazi/archive/2013/03/29/2988309.html