问题描述
- 计算机组成原理 浮点数的知识
-
想要学习这门课,可是被浮点数难倒了,哪位可以给我讲讲浮点数到底是怎么来的?里面的阶码,尾数的是怎么运算的?
还有怎么和十进制之间转换?
解决方案
科学计数法懂么?任何一个数,都可以表示为(-)0.xxxx * 10 ^ (-)n的形式
比如 1200 3.14 -0.00123 分别可以表示为 0.12 * 10^4 0.314 * 10^1和 -0.123 * -10^2
总之,我们可以用4个变量表示一个数,符号 尾数 指数的符号 指数,比如 -0.123 * -10^2,分别为 -,0.123, -, 2
二进制表示的浮点数也是一样,其中阶码就是指数,两个符号位各自需要1个二进制表示。
因此二进制浮点数转换为十进制其实也一样,你只要把尾数乘以对应2的阶码次方就可以。
解决方案二:
参考《那年声明理解不了定义与初始化》
http://blog.csdn.net/WinsenJiansbomber/article/details/50641687
回顾微机原理-浮点数
至于前面跳过一个细节,那就是小数 0.1,它在内存中的样子恐怕没人认识。这涉及到计算器原理,于是翻了翻谭老主编的《微机原理与接口技术》(ISBN 7-302-04603-4/TP·2726) 结果发现P20整数原码的表达式中的指数+号是错的,正确的是用-号。还是上网找资料书快,今天网络流行了,信息获取的迅速是最大的便利,也是最大的弊端,任何事都有两面。网络的泛滥也带来大量垃圾信息,因此信息过滤是网络世界的一个基础技能。
关于浮点数在 IEEE 标准中,将连续字节的所有二进制位分割为符号位,指数位和尾数位三个区。
符号位 Sign,占最高位1个比特,用 0 表示数值为正数,而 1 则表示负数。
指数位 Component,单精度数为 8 比特,双精度数为 11 比特。分别可以表示数值的范围0~255、0~2047,通过偏移值 (Bias),可以表达的数值分别为-127~128、-1023~1024,这样就可以表示指数的正负。实际的指数值的两个极植,以单精度说明,即 -127 以及 +128 保留用作特殊值,它们的二进位分别为全0和全1。这样,实际可以表达的有效指数范围就在 -127 和 127 之间。
尾数位 Mantissa,对于双精度浮点数,尾数位为剩下的52比特,单精度则为23比特。
为了节省内存,约定底数为2,小数点左边为1不记录,以科学记数法表示。例如,十进数10转换为单精度浮点数表示:
10D => 1010B => 1.01*2^3
=> 00000001 11010000 00000000 00000000 二进制表达
=> 00000001 10100000 00000000 00000000 省略小数点左边的1
=> 01000001 00100000 00000000 00000000 指数偏移127
=> 0x41200000 十六进制表达
以上变换过程可以用 Hex Workshop 来验证,或以前面的0.1来进行逆向转换:
0x401455 mov $0x9999999a,%eax
0x40145a mov $0x3fb99999,%edx
0x40145f mov %eax,-0x30(%ebp)
0x401462 mov %edx,-0x2c(%ebp)
寄存器 edx 的值存在高地址,根据 x86 使用的 Little-Endian规则,edx 的值也是高位,因此 0.1 的连续表达及转换过程:
0x3fb999999999999a 内存存储方式
=> 00111111 10111001 10011001 ... 10011001 10011010 二进制展开
=>0|0111111 1011|1001 10011001 ... 10011001 10011010 分割区域
=>0|0111111 1011|11001 10011001 ... 10011001 10011010 补整数1
=>提取符号位0,指数位去偏移-4,尾数1.10011001....
=>0.000110011...=>0*2^1 + 0*2^-1 + 0*2^-2 + 0*2^-3 + 1*2^-4 + 1*2^-5....
=>0.0625 + 0.03125 + ...
求值过程会发现,浮点运算是有精度丢失的问题的,因为 0.1 这种表达是一个近似值。
解决方案三:
为了表示浮点数,数被分为两部分:整数部分和小数部分.例如,浮点数14.234就有整数部分14和小数部分0.234.首先把浮点数转换成二进制数,步骤如下:1把整数部分转换成二进制.2把小数部分转换成二进制.3在两部分之间加上小数点.浮点数还可以规范化,浮点数可以用单精度表示法和双精度表示法.规范化只存储这个数的三个部分的信息:符号,指教和尾数.如+1000111.0101规范化后为
- 2^6 * 1.0001110101
符号 指数 尾数
规范化数的单精度表示法如+2^6*1.01000111001解:
由于符号为正,就用0表示.指数是6,在Excess_127表示法中,给指数加上127得到133.用二进制表示,就是10000101.尾数是01000111001.当把位数增加到32位,得到01000111001000000000000.注意不可以漏掉左边的0,因为它是小数.漏掉了那个0就相当于把这个数乘于2.这个数在内存中以32位数存储.如下所示
符号 指数 尾数
0 10000101 01000111001000000000000