黑马程序员技术交流社区
标题: 浮点数内存表现形式 [打印本页]
作者: rla540 时间: 2012-12-14 19:25
标题: 浮点数内存表现形式
本帖最后由 rla540 于 2012-12-14 19:27 编辑
黑马程序员---浮点数内存表现形式 有符号整数和无符号整数内存转换还是比较简单的。 那么浮点数说白了就是小数又是怎么转化的呢?由于计算机的构造适宜存储整数,所在小数的转化相对来说要复杂一些
6.25怎么转换加工变成0x40c80000的呢?
首先把10进制小数转换成二进制小数,6用除二取余法转换二进制后为 110
0.25 用乘2取整法转换为二进制小数点后的数01
6.25 = 110.01 二进制的小数点向左移动2位,最高位保留为1变成1.1001,小数点向左移动1位指数就加1,移动了2位所以指数加2; 因为所有二进制小数经过这样的转换后最高位都只会为1,所以这个1就可以去掉。只留下1001当往回转换成十进制时只要再把这个1加上即可。
6.25是正数,所以最高位符号位为0,后边8位为指数位这个小数的指数为2 所以是
011111111
+ 10
10000001
最后边23位由1001组成不足部分补0也就是
1001 0000 0000 0000 0000 000
最后把这32位二进制数全部输出看一下
01000000110010000000000000000000
再把这一串二进制数转换成16进制数得:
0100 0000 1100 1000 0000 0000 0000 0000
4 0 c 8 0 0 0 0
Ox40c80000那么在内存显示窗口中就表现为
00 00 c8 40
那么-6.25呢?只要把符号位从0变成1就行了:
1100 0000 1100 1000 0000 0000 0000 0000
C 0 C 8 0 0 0 0
那么在内存窗口中就显示为:00 00 C8 C0好我们验证下运行程序走
完全正确加10分,那么0.125又怎么转呢?
整数位为0所以不用转换了,只转小数部分转换后得二进制小数0.001,小数点向右移动3位得1.0 小数点向左每移一位指数就加1向右每移动一位自然就减1,所以指数部分得
01111111 + 11111101(-3的补码) = 01111100
因为是正数所以符号位为0, 小数点后为0所以最后面的23位全为0
0011 1110 0000 0000 0000 0000 0000 0000
3 E 0 0 0 0 0 0
所以内存中表示为 00 00 00 3E 看下程序是不是这样?
哈哈。正如所料
那么一个小数的小数部分转换二进制小数时乘不尽怎么办?那就一直乘下去,直到凑满23位为止。其余部分省略!那就拿0.025来说吧:不断乘2 得0.05, 0.1, 0.2, 0.4, 0.8, 1.6, 1.2,
0.4, 0.8, 1.6, 1.2, 0.4, 0.8。。。。。
0000 01 10 0110 0110 0110 0110 0110 0
小数点向右移动6位得1.10011001100110011001100
指数位 = 01111111 + 11111010(-6的补码) = 01111001
32位显示为
0011 1100 1100 1100 1100 1100 1100 1100
3 C C C C C C C
所以在内存窗口中应该显示为 cc cc cc 3c
和我们推出来的有点不一样?看看到底哪里不一样
0011 1100 1100 1100 1100 1100 1100 1100 我们推出得
0011 1100 1100 1100 1100 1100 1100 1101 实际显示的
我们发现只有最后末尾一位显示的不一样!最末尾的1100后边舍弃的数正好是1开头的,因此计算机对这个进制数进行了进位操作,类似于10进制中的四舍五入。
所以用浮点数存储小数都只会得到一个近似值!
Double数据类型的转换和float类似。那么decimal呢?这个我还真不知道!看了下反汇编代码,计算机在背后做了一系列复杂的操作。这种转换方法,我们也没必要一一全部知道。通过浮点数转换这几个事例,只是说明。所有类型,在计算机中都是二进制数据。不管你是int , double, class ,struct,还是for , while, 还是方法等,都是数据,唯一不同的就是对这些数据的解释,运算,操作不同罢了!
作者: 许庭洲 时间: 2012-12-14 19:55
值得学习ing!
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) |
黑马程序员IT技术论坛 X3.2 |