月初还在上班的时候,就天天盼望着过年放长假,然而终于熬到了过年,却发现自己的12天的长假将在碌碌无为中度过,朋友们又一个接一个的远去,心里真是拔凉拔凉的啊!最近版上的人气有点低落,连违规率(不敢说犯罪率哈,怕被人砍)都下降了不少,我想在春节这档子这是免不了的,论坛上应该有不上工作的朋友可能都回家团聚了。那像我这种无家可归的人除了眼馋别人的幸福,那就只有向仍然全力支持着我们C++/面向对象这个大家庭的兄弟姐妹们拜个年,祝来年薪水猛涨,职位高升,身体健康,家庭幸福!
最近一段时间看到版上关于C++里浮点变量精度的讨论比较多,那么我就给对这个问题有疑惑的人详细的讲解一下intel的处理器上是如何处理浮点数的。为了能更方便的讲解,我在这里只以float型为例,从存储结构和算法上来讲,double和float是一样的,不一样的地方仅仅是 float是32位的,double是64位的,所以double能存储更高的精度。还要说的一点是文章和程序一样,兼容性是有一定范围的,所以你想要完全读懂本文,你最好对二进制、十进制、十六进制的转换有比较深入的了解,了解数据在内存中的存储结构,并且会使用编译简单的控制台程序。 OK,下面我们开始。
大家都知道任何数据在内存中都是以二进制(1或着0)顺序存储的,每一个1或着0被称为1位,而在x86CPU上一个字节是8位。比如一个16位(2字节)的short int型变量的值是1156,那么它的二进制表达就是:00000100 10000100。由于Intel CPU的架构是Little Endian(请参数机算机原理相关知识),所以它是按字节倒序存储的,那么就因该是这样:10000100 00000100,这就是定点数1156在内存中的结构。
那么浮点数是如何存储的呢?目前已知的所有的C/C++编译器都是按照IEEE (国际电子电器工程师协会)制定的IEEE 浮点数表示法来进行运算的。这种结构是一种科学表示法,用符号(正或负)、指数和尾数来表示,底数被确定为2,也就是说是把一个浮点数表示为尾数乘以2的指数次方再加上符号。下面来看一下具体的float的规格: