- 浏览: 508903 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
jkxydp:
算法运行的结果根本就不对。
BM算法. -
soarwindzhang:
感谢博主的分享,我今天看了您的UFSET非递归的路径压缩时感觉 ...
并查集 -
zhangning290:
楼主好像只考虑了坏字符规则,。没有考虑好后缀
BM算法. -
lsm0622:
文字描述有错误 误导新学者
求有向图的强连通分量(scc):Tarjan算法 -
knightchen:
博主,你太强了!这篇文章对我学习C++多线程很有帮助!谢谢
并发学习之一_windows下ZThread在CodeBlocks上的安装与配置
[转载]http://blog.csdn.net/masefee/archive/2010/01/30/5272554.aspx
这里历史和发展就不说了,直接从IEEE浮点标准说起。
在 IEEE 标准中,浮点数是将特定长度的连续字节的所有二进制位分割为特定宽度的符号域,指数域和尾数域三个域,其中保存的值分别用于表示给定二进制浮点数中的符号,指数和尾数。这样,通过尾数和可以调节的指数(所以称为"浮点")就可以表达给定的数值了。
具体的格式:
注:浮点数在32位机子上有两种精度,float占32位,double占64位。
我们应该不要特殊看到浮点数的内存存储形式,它跟整数没有什么区别,只是在这4字节或者8字节里有3个区域,整数有符号只有符号位及后面的数值。
那么,我们先来看32位浮点数 的换算:
1. 从浮点数到16进制数
float var = 5.2f;
就这个浮点数,我们一步一步将它转换为16进制数。
首先,整数部分5,二进制表示为:0101。
其次,小数部分0.2,转换为二进制的计算方法,那么就是依次乘以2,取整数部分作为二进制数,取小数部分继续乘以2,一直算到小数结果为0为止。那么对0.2进行计算:
0.2的二进制就计算出来了,结果就为:0.00110011... ...
这里的省略号是你没有办法计算完。二进制序列无限循环,没有到达结果为0的那一天。那么此时我们该怎么办?
这里就得取到一定的二进制位数后停止计算,然后舍入。我们知道,float是32位,后面尾数的长度只能最大23位。因此,计算结束的时候,整数部分加上小数部分的二进制一共23位二进制。
因此5.2 的二进制表示就为:
一共23位。
此时,使用科学计数法表示,结果为:
由于我们规定,使用二进制科学计数法后,小数点左边必须为1,这样这个1就不用存储了,我们在从16进制数换算到浮点数的时候加上这个1就是了,省略到这个1的目的是为了后面的小数部分能够多表示一位,精度就更高一些了哟。
那么省略到小数点前面的1后的结果为:
这里后面蓝色的0就是补上的,这里不是随便补的一个0,而是0.2的二进制在这一位上本来就应该为0,如果该为1,我们就得补上一个1.
但是,在对阶或向右规格化时,尾数要向右移位,这样被右移的尾数的低位部分会被丢掉,从而造成一定的误差,因此要进行舍入处理。 常用的舍入方法有两种:一种是“0舍1入”法,即如果右移时被丢掉数位的最高位为0则舍去,为1则将尾数的末位加“1”,另一种是“恒置1”,即只要数位被移掉,就在尾数的末位恒置“1”。
举个例子:
123.456的二进制到23位时:111 1011.0111 0100 1011 1100 01...
后面还有依次为01...等低位,由于最高位的1会被隐藏,向后扩展一位如果不做舍入操作则结果为:
1.11 1011 0111 0100 1011 1100 0 * 2^6
但是经过舍入操作后,由于被舍掉的位的最高位是1,或者“恒置1”法,最后面的0都应该是1。因此最终就应该是:
1.11 1011 0111 0100 1011 1100 1 * 2^6
在这里需要说明,不管是恒置1,还是0舍1入法,其根本都是为了减小误差。
5.2的尾数在这里就计算好了,就是: 01001100110011001100110
再来看阶数,这里我们知道是2^2次方,那么指数就是2。同样IEEE标准又规定了,因为中间的阶码在float中是占8位,而这个阶码又是有符号的(意思就是说,可以有2^-2次方的形式)。注意这里偏置量的概念:
float 类型的偏置量 Bias = 2^(k-1) -1 = 2^(8-1) -1 = 127 ,但还要补上刚才因为左移作为小数部分的 2 位(也就是科学技术法的指数),因此阶码为 127 + 2=129 ,就是 IEEE 浮点数表示标准:
这里的阶码就是129,二进制就是:10000001
因此,拼接起来后:
还原:
这里因为之前我们都知道有个固定的1给省略了,因此这里要给加上去。加上去之后:
1 010 0110 0110 0110 0110 011 0
这里是24位,我们先不管,小数点添进去:
1 . 010 0110 0110 0110 0110 011 0 * 2^2
然后将科学计数法变换成普通的二进制小数:
1 01 . 0 0110 0110 0110 0110 011 0
到这里,就真正可以把整数部分换成十进制了:
1 01 . 0 0110 0110 0110 0110 011 0
5. xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
我们知道了,整数部分是5,后面的小数部分再进行逆运算:
0 . 0 0110 0110 0110 0110 011 0 =
0 + 0*2^-1 + 0*2^-2 + 1*2^-3 + 1*2^-4 + 0*2^-5 + 0*2^-6 + 1*2^-7 + ... ... + 0*2^-21 这样一个式子,我们算出结果来,放在浮点数里:
5.1999998。
因此我们可以看到精度已经有损失了。
64位浮点数 的换算:
这里就不再具体说明怎么换算的了,只需要提到2个地方:
一是,中间的阶码在double中占有11位,因此阶码就不是+127了,而是加上1023,因为11位能表示的最大无符号数是2047,因此有符号范围[-1024, 1023]。
二是,尾数是52位,因此精度更高,能表示的数也就越大。我们在换算5.2的时候,后面的小数二进制+前面的5的二进制再省略一位后的总位数要填满52位。
给出一段验证代码:
这里历史和发展就不说了,直接从IEEE浮点标准说起。
在 IEEE 标准中,浮点数是将特定长度的连续字节的所有二进制位分割为特定宽度的符号域,指数域和尾数域三个域,其中保存的值分别用于表示给定二进制浮点数中的符号,指数和尾数。这样,通过尾数和可以调节的指数(所以称为"浮点")就可以表达给定的数值了。
具体的格式:
符号位 阶码 尾数 长度 |
float 1 8 23 32 |
double 1 11 52 64 |
注:浮点数在32位机子上有两种精度,float占32位,double占64位。
我们应该不要特殊看到浮点数的内存存储形式,它跟整数没有什么区别,只是在这4字节或者8字节里有3个区域,整数有符号只有符号位及后面的数值。
那么,我们先来看32位浮点数 的换算:
1. 从浮点数到16进制数
float var = 5.2f;
就这个浮点数,我们一步一步将它转换为16进制数。
首先,整数部分5,二进制表示为:0101。
其次,小数部分0.2,转换为二进制的计算方法,那么就是依次乘以2,取整数部分作为二进制数,取小数部分继续乘以2,一直算到小数结果为0为止。那么对0.2进行计算:
0.2*2 = 0.4 * 2 = 0.8 * 2 = 1.6(0.6) * 2 = 1.2(0.2)*2 = 0.4 * 2 = 0.8 * 2 = 1.6(0.6) * 2 = 1.2 ... ... |
00110011... ... |
0.2的二进制就计算出来了,结果就为:0.00110011... ...
这里的省略号是你没有办法计算完。二进制序列无限循环,没有到达结果为0的那一天。那么此时我们该怎么办?
这里就得取到一定的二进制位数后停止计算,然后舍入。我们知道,float是32位,后面尾数的长度只能最大23位。因此,计算结束的时候,整数部分加上小数部分的二进制一共23位二进制。
因此5.2 的二进制表示就为:
101.00110011001100110011 |
一共23位。
此时,使用科学计数法表示,结果为:
1.0100110011001100110011 * 2^2 |
由于我们规定,使用二进制科学计数法后,小数点左边必须为1,这样这个1就不用存储了,我们在从16进制数换算到浮点数的时候加上这个1就是了,省略到这个1的目的是为了后面的小数部分能够多表示一位,精度就更高一些了哟。
那么省略到小数点前面的1后的结果为:
.01001100110011001100110 * 2^2 |
这里后面蓝色的0就是补上的,这里不是随便补的一个0,而是0.2的二进制在这一位上本来就应该为0,如果该为1,我们就得补上一个1.
但是,在对阶或向右规格化时,尾数要向右移位,这样被右移的尾数的低位部分会被丢掉,从而造成一定的误差,因此要进行舍入处理。 常用的舍入方法有两种:一种是“0舍1入”法,即如果右移时被丢掉数位的最高位为0则舍去,为1则将尾数的末位加“1”,另一种是“恒置1”,即只要数位被移掉,就在尾数的末位恒置“1”。
举个例子:
123.456的二进制到23位时:111 1011.0111 0100 1011 1100 01...
后面还有依次为01...等低位,由于最高位的1会被隐藏,向后扩展一位如果不做舍入操作则结果为:
1.11 1011 0111 0100 1011 1100 0 * 2^6
但是经过舍入操作后,由于被舍掉的位的最高位是1,或者“恒置1”法,最后面的0都应该是1。因此最终就应该是:
1.11 1011 0111 0100 1011 1100 1 * 2^6
在这里需要说明,不管是恒置1,还是0舍1入法,其根本都是为了减小误差。
5.2的尾数在这里就计算好了,就是: 01001100110011001100110
再来看阶数,这里我们知道是2^2次方,那么指数就是2。同样IEEE标准又规定了,因为中间的阶码在float中是占8位,而这个阶码又是有符号的(意思就是说,可以有2^-2次方的形式)。注意这里偏置量的概念:
float 类型的偏置量 Bias = 2^(k-1) -1 = 2^(8-1) -1 = 127 ,但还要补上刚才因为左移作为小数部分的 2 位(也就是科学技术法的指数),因此阶码为 127 + 2=129 ,就是 IEEE 浮点数表示标准:
V = (-1)^s × M × 2^(e - Bias) |
s:符号位 M:尾数 e:阶码 |
这里的阶码就是129,二进制就是:10000001
因此,拼接起来后:
还原:
这里因为之前我们都知道有个固定的1给省略了,因此这里要给加上去。加上去之后:
1 010 0110 0110 0110 0110 011 0
这里是24位,我们先不管,小数点添进去:
1 . 010 0110 0110 0110 0110 011 0 * 2^2
然后将科学计数法变换成普通的二进制小数:
1 01 . 0 0110 0110 0110 0110 011 0
到这里,就真正可以把整数部分换成十进制了:
1 01 . 0 0110 0110 0110 0110 011 0
5. xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
我们知道了,整数部分是5,后面的小数部分再进行逆运算:
0 . 0 0110 0110 0110 0110 011 0 =
0 + 0*2^-1 + 0*2^-2 + 1*2^-3 + 1*2^-4 + 0*2^-5 + 0*2^-6 + 1*2^-7 + ... ... + 0*2^-21 这样一个式子,我们算出结果来,放在浮点数里:
5.1999998。
因此我们可以看到精度已经有损失了。
64位浮点数 的换算:
这里就不再具体说明怎么换算的了,只需要提到2个地方:
一是,中间的阶码在double中占有11位,因此阶码就不是+127了,而是加上1023,因为11位能表示的最大无符号数是2047,因此有符号范围[-1024, 1023]。
二是,尾数是52位,因此精度更高,能表示的数也就越大。我们在换算5.2的时候,后面的小数二进制+前面的5的二进制再省略一位后的总位数要填满52位。
给出一段验证代码:
#include <stdio.h> #include <string.h> int main() { union { float f; int i; }u; u.f = 5.2f; printf("%.7f\n", u.f); //5.1999998一旦放入,精度已经发生了变化 printf("%x\n", u.i); union { float f; int i; }v; v.i = 0x40A66666; printf("%.7f\n", v.f); printf("%x\n", v.i); return 0; }
发表评论
-
C语言中的不定参数
2010-12-15 12:28 130901,最近刚刚知道C语言还有不定参数这么个东东。 2,解决方法 ... -
存在虚基类时,类对象的大小
2010-12-09 19:38 11941, 实例代码: #include <iostrea ... -
关于父类的构造的顺序
2010-12-09 19:33 6391,没有虚基类的情况: #include <iost ... -
关于empty class的大小
2010-12-09 19:32 10941,首先简要说明下为什么empty class的大小不是0? ... -
JVM实现机制及内部基本概念
2010-12-09 19:27 844兴趣所致,搜了一些关于JVM的简单介绍,算是扫盲吧。 1.J ... -
指向对象成员变量的指针。
2010-12-09 19:18 11341,工作定了后,把《Inside the C++ object ... -
面向对象的一些常见问题总结。
2010-12-09 19:08 8991,构造函数中调用虚函数的问题。 注:一般编译器都会在执行完b ... -
关于C++的名字查找规则
2010-12-09 19:05 13561,总结一句话:由内向外,找到合适的即刻停止。 实例代码: ... -
继承下的名字查找规则,最近作用域
2010-11-06 20:04 8701, #include <iostream> ... -
虚基类和多重继承总结
2010-11-06 19:54 8541,虚基类,其构造函数总是在最后一个层次最先并且真正被执行。 ... -
为什么构造函数,不能是virtual?
2010-09-25 15:24 16661,C++语言是静态语言,而把构造函数写成虚函数意味这可以动态 ... -
大小端对应字节, 注意和一个字节内位序的区分
2010-09-09 10:11 14021,一个例子: #include <stdio.h& ... -
实现:不能被继承的类
2010-08-31 17:35 8411,首先想到的是在C++ 中 ... -
提升为N的倍数(N为2的指数次)
2010-07-18 10:16 7631,可以这么做: int num=15; num = (num ... -
C++ 中:new的用法
2010-07-17 16:26 1902先放这儿,有时间了,在 ... -
句柄的使用实例
2010-06-02 11:24 11681,这个实例采用了使用计数策略. 2,实例代码: #in ... -
关于类的一些语法:
2010-06-02 09:26 701所谓"书越读越薄",这话说得真是有道理. ... -
sizeof(string对象)的大小
2010-06-01 11:32 15311,无语了,string对象的大小固定就是4啊. 2,实例代码 ... -
C语言中不同增值语句的区别
2010-05-12 12:50 6571, mango[i++]+=y; 被当作 mango[i]= ... -
尽量不要在一个表达式中有多个副作用
2010-05-02 10:48 10301,一般来说,编c/c++程序有一个纪律:一个语句中不要有两个 ...
相关推荐
浮点数的DFA识别算法是一种在计算机编程中用于解析和验证输入字符串是否符合浮点数格式的方法。DFA(确定有限状态自动机)是一种计算模型,它通过一系列预...在实际应用中,这种算法常用于编译器前端的词法分析阶段。
使用这样的替换文件,开发者可以在保持系统性能的同时,方便地在RTT中查看和分析浮点数变量的变化,这对于调试和性能调优非常有帮助。总的来说,理解和掌握浮点数在JLINK RTT中的打印方法,对于提升嵌入式系统的开发...
这个工具对于理解和分析浮点数在计算机系统中的表示方式非常有用,尤其在编程、硬件设计或科学计算领域。 IEEE 754是国际电工委员会(IEEE)制定的一套浮点数运算标准,广泛应用于各种计算机系统中。该标准定义了...
### 浮点数计算与误差分析 #### 一、浮点数的基本概念 浮点数是一种用于表示实数的数据类型,广泛应用于计算机科学中的数值计算领域。为了更好地理解浮点数及其运算中可能出现的误差问题,我们需要从浮点数的表示...
64位浮点数,也称为双精度浮点数,按照IEEE 754标准,它能够提供高精度的数值计算,适用于需要精确计算的场合,如科学计算、财务分析等。这种数据类型由32位指数部分、11位尾数部分和1位符号位组成,可以表示从大约-...
在IT领域,尤其是在编程和数据分析中,数据的表示和转换是非常关键的部分。本文将深入探讨十六进制到浮点数的转换,特别是在LabVIEW环境下的实现。LabVIEW(Laboratory Virtual Instrument Engineering Workbench)...
这样的工具集成为开发者和数据分析师提供了便捷的计算支持,避免手动转换带来的错误和不便。 总的来说,理解和掌握浮点数的十六进制转换对于理解计算机如何处理和存储数字至关重要。这个工具不仅方便了专业人士的...
理解并熟练掌握HEX与浮点数的相互转换对于任何从事软件开发、系统分析或者底层编程的人来说都是基础技能。它有助于深入理解计算机内部的工作机制,特别是在处理数值精度问题、调试内存数据或与硬件交互时。
通过分析这些文件,我们可以深入理解转换算法的实现细节,以及如何在S7-200SMART PLC中执行此操作。源文件提供了清晰的编程思路,库文件则封装了转换函数,方便在实际项目中调用。程序注释对于理解和调试代码至关...
浮点数表示方式的应用非常广泛,例如在科学计算、工程计算、数据分析等领域都需要使用浮点数表示方式。因此,了解浮点数表示方式的原理和方法是非常重要的。 在现实应用的计算机系统中,采用的是 IEEE754 格式。...
通过阅读和分析代码,可以加深对转换过程的理解,并可能从中学习到一些实用的编程技巧。 总结来说,浮点数与十六进制的转换是单片机编程中的重要技能,涉及到二进制、IEEE 754浮点数表示法、位运算等多个概念。掌握...
4. **精度分析**:分析计算过程中可能出现的舍入误差,这对于数值计算和科学计算非常重要。 5. **异常处理**:显示和处理浮点异常,如无穷大、NaN(非数字)和下溢/上溢。 6. **比较功能**:比较两个IEEE 754...
总结来说,“4字节浮点数计算工具”是电力通信领域中一个实用的辅助工具,它结合了浮点数的4字节表示、16进制与10进制之间的转换,以及对通信规约报文的理解和分析。这样的工具对于提高工作效率,确保数据的正确解析...
本篇文章将深入探讨浮点数加法在C++中的实现,并结合POJ(Programming Online Judge)平台的题目,分析大浮点数加法的处理方法。 首先,C++中的浮点数加法通常通过标准库中的`+`运算符完成。例如: ```cpp float ...
**正文** IEEE754浮点数标准是计算机科学中用于表示和操作浮点数的国际标准,由电气...无论是软件开发、数据分析还是硬件设计,都可能涉及到浮点数的处理和转换,因此深入学习这一主题将对提升技术能力产生积极影响。
#### 五、示例分析 以下是一个具体的例子,演示如何将十进制数转换为符合IEEE 754标准的32位浮点数表示: - **原始值**:20.59375 - **转换步骤**: 1. 将20.59375转换为二进制形式:10100.10011 2. 归一化为:1...
通过以上分析,我们可以看到LabVIEW结合MXComponentlabview库为三菱FX系列PLC提供了强大的编程支持,允许用户高效地实现浮点数的读写操作。对于PLC自动化项目,理解并熟练掌握这些工具和技巧至关重要。
本文旨在深入剖析Intel IA32架构下C语言中的浮点数机制,通过具体的代码示例和理论分析,解释浮点数在不同精度下的表现差异,以及在实际编程过程中可能遇到的问题。 #### 浮点数的基本概念 浮点数是一种用来表示...
浮点数计算是计算机科学中的一个关键领域,特别是在数值计算、科学计算以及工程应用中扮演着重要角色。然而,由于浮点数在计算机中的表示方式和计算过程中的限制,浮点计算往往会产生误差。这篇自己编写的分析文章...
2. 分析二进制表示:解析这四个字节,提取符号位、指数和尾数。 3. 解码指数和尾数:指数部分需要进行偏移(bias)处理,尾数部分则需要考虑隐藏位(隐含的1)和规格化。 4. 计算浮点数:根据解码的结果,计算实际的...