C/C++浮点数简述一:模型
2013-10-31 11:38
239 查看
c/c++采用IEEE表示法存储浮点类型,公式为:
[align=justify](-1)s x M x 2 E[/align]
[align=justify]其中:[/align]
[align=justify]s是符号位,决定正数(0)还是负数(-1),数值为0的数字符号位做特殊处理。[/align]
[align=justify]M是二进制有效数。[/align]
[align=justify]E是2的幂,作用是对2进制加权。[/align]
[align=justify]那么在C中,存储格式如下:[/align]
[align=justify]0(1位) | 1-23(23 位) | 24-31(8位 ) | 32位[/align]
[align=justify]0(1位) | 1-52(52 位) | 53-63(11位 ) |64 位[/align]
[align=justify] [/align]
[align=justify] [/align]
[align=justify]而根据 E的值的不同浮点数的表示方法有一下三种:[/align]
[align=justify]规范化值:[/align]
[align=justify]E为无符号数,当E不是全 0或者全1 时,此时就是用于规范化表示。[/align]
[align=justify]E = e-bias,e 为k位, k为E 的位数, bias为2 k-1 ,由此确定,E的取值范围[/align]
[align=justify]对于单精度来说是 -126 - +127,双精度为-1022 - + 1023 。[/align]
[align=justify]M=f+1(0<=f<1 ),即二进制值为 0.fn-1 fn-2…f 1f0 ,需要注意的是 隐含的1 ,因为我们总是能够调节指数,使 1<=M<2,那么小数第一位肯定是 1,而这个1 我们就不用显示的表示它了,这样可以获得额外一位。 [/align]
[align=justify]非规范化值:[/align]
[align=justify] 当指数E 二进制位全 0时,所表现的数就是非规范化形式的,这种情况下指数值为 E=1-bias,[/align]
[align=justify]而M=f,此时 1不被隐含。因为规格化时有一个隐含的 1,所以不能表示0,而规范化值可以表示 0。+0和负0在IEEE标准中是是不一样的,但是C库是不区分的,但有个例外:1/负0结果是负无穷,而1/正0结果是正无穷。正0和负0比较是一样的。我觉得C库应该是在0参与的运算当中是区分正负的,但是直接比较0时,是不区分的。这里使用1-bias 是为了从非规范化值向规范化值的平滑转换,非规范化值的最大表示恰巧是规范化值的最小表示,此时转换,我们只需要将 e转为1 ,再加上一个隐含 1就可以完成。[/align]
[align=justify]特殊值:[/align]
[align=justify]当指数值 E为全1 ,M全为 0时,表示的值是无穷,当 s为0 时,表示的是正无穷,当 s为1 时,表示的是负无穷,当小数值不为 0时,结果为NaN ,即不是一个数,如求 -1的开根。[/align]
[align=justify]具体的IEEE标准可以参看wiki http://zh.wikipedia.org/wiki/IEEE_754[/align]
[align=justify](-1)s x M x 2 E[/align]
[align=justify]其中:[/align]
[align=justify]s是符号位,决定正数(0)还是负数(-1),数值为0的数字符号位做特殊处理。[/align]
[align=justify]M是二进制有效数。[/align]
[align=justify]E是2的幂,作用是对2进制加权。[/align]
[align=justify]那么在C中,存储格式如下:[/align]
[align=justify]s[/align] | [align=justify]f(M=1+f orM=f)[/align] | [align=justify]e(E=e-bias ,bias 为 2k-1 , k为 E 的位数)[/align] |
[align=justify]0(1位) | 1-52(52 位) | 53-63(11位 ) |64 位[/align]
[align=justify] [/align]
[align=justify] [/align]
[align=justify]而根据 E的值的不同浮点数的表示方法有一下三种:[/align]
[align=justify]规范化值:[/align]
[align=justify]E为无符号数,当E不是全 0或者全1 时,此时就是用于规范化表示。[/align]
[align=justify]E = e-bias,e 为k位, k为E 的位数, bias为2 k-1 ,由此确定,E的取值范围[/align]
[align=justify]对于单精度来说是 -126 - +127,双精度为-1022 - + 1023 。[/align]
[align=justify]M=f+1(0<=f<1 ),即二进制值为 0.fn-1 fn-2…f 1f0 ,需要注意的是 隐含的1 ,因为我们总是能够调节指数,使 1<=M<2,那么小数第一位肯定是 1,而这个1 我们就不用显示的表示它了,这样可以获得额外一位。 [/align]
[align=justify]非规范化值:[/align]
[align=justify] 当指数E 二进制位全 0时,所表现的数就是非规范化形式的,这种情况下指数值为 E=1-bias,[/align]
[align=justify]而M=f,此时 1不被隐含。因为规格化时有一个隐含的 1,所以不能表示0,而规范化值可以表示 0。+0和负0在IEEE标准中是是不一样的,但是C库是不区分的,但有个例外:1/负0结果是负无穷,而1/正0结果是正无穷。正0和负0比较是一样的。我觉得C库应该是在0参与的运算当中是区分正负的,但是直接比较0时,是不区分的。这里使用1-bias 是为了从非规范化值向规范化值的平滑转换,非规范化值的最大表示恰巧是规范化值的最小表示,此时转换,我们只需要将 e转为1 ,再加上一个隐含 1就可以完成。[/align]
[align=justify]特殊值:[/align]
[align=justify]当指数值 E为全1 ,M全为 0时,表示的值是无穷,当 s为0 时,表示的是正无穷,当 s为1 时,表示的是负无穷,当小数值不为 0时,结果为NaN ,即不是一个数,如求 -1的开根。[/align]
[align=justify]具体的IEEE标准可以参看wiki http://zh.wikipedia.org/wiki/IEEE_754[/align]
相关文章推荐
- uva10344 一次AC
- C语言实现一个简单的猜数字游戏
- c++中sizeof的分析
- 面向对象的设计(一)——C++高级编程
- C++ Primer 第三章 标准库string类型
- 配置vim编译c/c++
- C++读写文件
- C++ 文件hash值 BT种子的hash值
- OpenCV Learning: imwrite in C++
- c/c++中const详解
- c/c++中typedef详解
- C++拷贝构造函数详解
- C++二进制查找
- VC++ 线程池(h)
- 【存】C语言中#if,#ifdef
- VC++ 如何识别系统语言类别
- c++ 二维数组
- C语言书单
- 【转】C++信号量Semaphore和MFC中的CSemaphore类使用【转】
- C++ Primer学习 第二章