浮点数在内存中的表示方法_第1页
浮点数在内存中的表示方法_第2页
浮点数在内存中的表示方法_第3页
浮点数在内存中的表示方法_第4页
浮点数在内存中的表示方法_第5页
已阅读5页,还剩2页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、.浮点数在内存中的表示方法浮点数保存的字节格式如下:地址+0+1+2+3内容seee eeeeemmm mmmmmmmm mmmmmmmmmmmm这里s 代表符号位, 1 是负, 0 是正e 偏移 127 的幂,二进制阶码 =(eeeeeeee)-127 。m 24 位的尾数保存在 23 位中,只存储 23 位,最高位固定为 1。此方法用最较少的位数实现了较高的有效位数,提高了精度。零是一个特定值,幂是0 尾数也是 0。浮点数 -12.5作为一个十六进制数 0xc1480000保存在存储区中,这个值如下:地址 +0+1+2+3内容 0xc10x480x000x00浮点数和十六进制等效保存值之间

2、的转换相当简单。下面的例子说明上面的值-12.5 如何转换。浮点保存值不是一个直接的格式, 要转换为一个浮点数, 位必须按上面的浮点数保存格式表所列的那样分开,例如:地址+0+1+2+3格式seee eeeeemmm mmmmmmmm mmmmmmmmmmmm二进制11000001010010000000000000000000十六进制c1480000从这个例子可以得到下面的信息:符号位是 1 表示一个负数幂是二进制 10000010 或十进制 130 , 130 减去 127 是 3,就是实际的幂。尾数是后面的二进制数10010000000000000000000在尾数的左边有一个省略的小数

3、点和 1,这个 1 在浮点数的保存中经常省略 ,加上一个 1 和小数点到尾数的开头 ,得到尾数值如下 :.1.10010000000000000000000接着 ,根据指数调整尾数 .一个负的指数向左移动小数点 .一个正的指数向右移动小数点 .因为指数是 3,尾数调整如下 :1100.10000000000000000000结果是一个二进制浮点数, 小数点左边的二进制数代表所处位置的2 的幂,例如:1100 表示(1*23)+(1*22)+(0*21)+(0*20)=12。小数点的右边也代表所处位置的2 的幂,只是幂是负的。例如:.100. 表示(1*2(-1)+(0*2(-2)+(0*2(-

4、2).=0.5。这些值的和是 12.5 。因为设置的符号位表示这数是负的,因此十六进制值0xc1480000 表示 -12.5 。所有的 c/c+编译器都是按照 ieee(国际电子电器工程师协会)制定的 iee e 浮点数表示法来进行运算的。 这种结构是一种科学表示法, 用符号(正或负)、指数和尾数来表示,底数被确定为 2,也就是说是把一个浮点数表示为尾数乘以2 的指数次方再加上符号。下面来看一下具体的规格:符号位指数位小数部分指数偏移量单精度浮点数1位 318 位 30-2323 位 22-00127双精度浮点数1位 6311 位 62-5252 位51-001023我们以单精度浮点 数来说

5、明:指数是 8 位,可表达的范围是0 到 255而对应的实际的指数是127 到 128这里特殊说明, 127 和 128 这两个数据在 ieee 当中是保留的用作多种用途的127 表示的数字是 0128 和其他位数组合表示多种意义,最典型的就是nan状态.从存储结构和算法上来讲,double 和 float是一样的,不一样的地方仅仅是 float 是 32 位的, double 是 64 位的,所以 double 能存储更高的精度任何数据在内存中都是以二进制 (1 或着 0)顺序存储的, 每一个 1 或着 0 被称为 1 位,而在 x86cpu上一个字节是 8 位。比如一个 16 位( 2 字

6、节)的 short int 型变量的值是 1156,那么它的二进制表达就是: 00000100 10000100。由于 intel cpu 的架构是 little endian (请参数机算机原理相关知识),所以它是按字节倒序存储的,那么就因该是这样: 10000100 00000100,这就是定点数 1156 在内存中的结构 .我们先不考虑逆序存储 的问题,先按照顺序的来讲, 最后再把他们翻过来就行了。现在让我们按照 ieee 浮点数表示法, 一步步的将 float型浮点数 123456.0f 转换为十六进制代码。在处理这种不带小数的浮点数时,直接将整数部转化为二进制表示: 1 111000

7、10 01000000 也可以这样表示: 11110001001000000.0 然后将小数点向左移,一直移到离最高位只有1 位,就是最高位的1:1.11100010010000000 一共移动了 16 位,在布耳运算中小数点每向左移一位就等于在以2为底的科学计算法表示中指数+1,所以原数就等于这样: 1.11100010010000000* ( 2 16 ) 好了,现在我们要的尾数和指数都出来了。 显而易见,最高位永远是 1,因为你不可能把买了 16 个鸡蛋说成是买了 0016 个鸡蛋吧?(呵呵,可别拿你买的臭鸡蛋甩我 ),所以 这个 1 我们还有必要保留他吗?(众:没有!)好的,我们删掉他

8、。这样尾数的二进制就变成了: 11100010010000000最后在尾数的后面补 0,一直到补够 23 位:11100010010000000000000( md,这些个 0 差点没把我数的背过气去 )再回来看指数, 一共 8 位,可以表示范围是 0 - 255 的无符号整数, 也可以表示 -128 - 127 的有符号整数。但因为指数是可以为负的,所以为了统一把十进制的整数化为二进制时,都先加上127,在这里,我们的16 加上 127 后就变.成了 143,二进制表示为: 10001111 12345.0f这个数是正的,所以符号位是0,那么我们按照前面讲的格式把它拼起来:0 1000111

9、1 1110001001000000000000001000111 11110001 00100000 00000000再转化为 16 进制为: 47 f1 20 00 ,最后把它翻过来,就成了:00 20 f147。有了上面的基础后, 下面我再举一个带小数的例子来看一下为什么会出现精度问题。按照 ieee浮点数表示法,将 float型浮点数 123.456f 转换为十六进制代码。对于这种带小数的就需要把整数部和小数部分开处理。整数部直接化二进制:100100011。小数部的处理比较麻烦一些,也不太好讲,可能反着讲效果好一点,比如有一个十进制纯小数 0.57826 ,那么 5 是十分位,位阶是

10、 1/10 ;7 是百分位,位阶是 1/100 ;8 是千分位,位阶是 1/1000 ,这些位阶分母的关系是 101、102、103,现假设每一位的序列是s1、s2、s3、 sn,在这里就是5、7、8、2、6,而这个纯小数就可以这样表示:n = s1 * ( 1 / ( 10 1 ) )+ s2 * ( 1 / ( 10 2 ) ) + s3 * ( 1 / ( 10 3 ) ) + + sn * (1 / ( 10 n ) )。把这个公式推广到b 进制纯小数中就是这样:n = s1 * ( 1 / ( b 1 ) ) + s2 * ( 1 / ( b 2 ) ) + s3 * ( 1 / (

11、 b 3 ) ) + + sn * ( 1 / ( b n ) )天哪,可恶的数学,我怎么快成了数学老师了!没办法,为了广大编程爱好者的切身利益, 喝口水继续!现在一个二进制纯小数比如0.100101011 就应该比较好理解了,这个数的位阶序列就因该是1/(21) 、1/(22) 、1/(23) 、1/(24) ,即 0.5 、0.25 、0.125 、0.0625 。乘以 s 序列中的 1 或着 0 算出每一项再相加就可以得出原数了。现在你的基础知识因该足够了,再回过头来看0.45这个十进制纯小数, 化为该如何表示呢?现在你动手算一下,最好不要先看到答案,这样对你理解有好处。.注:这里小数点

12、的转换比较麻烦,可以用小数和2 相乘,如果有各位为1,则写上 1,相乘的结果减掉1,继续。我想你已经迫不及待的想要看答案了, 因为你发现这跟本算不出来! 来看一下步骤: 1 / 2 1 位(为了方便,下面仅用 2 的指数来表示位), 0.456 小于位阶值 0.5 故为 0;2 位, 0.456 大于位阶值 0.25 ,该位为 1,并将 0.45 减去 0.2 5 得 0.206 进下一位; 3 位, 0.206 大于位阶值 0.125 ,该位为 1,并将 0.206 减去 0.125 得 0.081 进下一位; 4 位, 0.081 大于 0.0625 ,为 1,并将 0.081 减去0.0

13、625 得 0.0185 进下一位; 5 位 0.0185 小于 0.03125 ,为 0问题出来了,即使超过尾数的最大长度23 位也除不尽!这就是著名的浮点数精度问题了(浮点十进制值通常没有完全相同的二进制表示形式。这是cpu 所采用的浮点数据表示形式的副作用。 为此,可能会经历一些精度丢失, 并且一些浮点运算可能会产生意外的结果。)。不过我在这里不是要给大家讲数值计算,用各种方法来提高计算精度, 因为那太庞杂了, 恐怕我讲上一年也理不清个头绪啊。我在这里就仅把浮点数表示法讲清楚便达到目的了。ok,我们继续。嗯,刚说哪了?哦对对,那个数还没转完呢,反正最后一直求也求不尽,加上前面的整数部算够

14、24 位就行了: 1111011.01110100101111001。某 bc问:“不是 23 位吗?”我:“倒,不是说过了要把第一个 1 去掉吗?当然要加一位喽! ”现在开始向左移小数点, 大家和我一起移, 众:“ 1、2、3”好了,一共移了 6 位,6 加上 127 得 131(怎么跟教小学生似的?呵呵 ),二进制表示为: 10000101,符号位为再不说了, 越说越啰嗦,大家自己看吧:0100001011110110111010010111100142f6e97979e9f642下面再来讲如何将纯小数转化为十六进制。对于纯小数,比如0.0456 ,我们需要把他规格化,变为1.xxxx *( 2 n)的型式,要求得纯小数x 对应的 n 可用下面的公式:n = int( 1 + log (2)x );.0.0456 我们可以表示为1.4592

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论