float和double类型介绍

写在前面:

   在实习公司写了一个传感器的驱动程序,传感器数据有时会出现异常值,有时正常。把计算过程的临时变量由整形定义为double类型后异常值不再出现。后来定位到出错原因,是因为整形(32位)临时变量溢出,解决方法是计算时把临时变量强制类型转换为范围较大的整形(64位),或者直接用64位整形。

       用double类型之所以不会出错,是因为double类型计算时都自动转为double类型了。double类型表示范围大,不存在溢出问题。其实用float也不会出问题。

下面说一下float和double类型。

float和double分别称为单精度和双精度浮点型,它们的区别如下:

单精度浮点数(float)与双精度浮点数(double)的区别如下:

(1)在内存中占有的字节数不同

·        单精度浮点数在机内占4个字节

·        双精度浮点数在机内占8个字节

(2)有效数字位数不同

·        单精度浮点数有效数字8位

·        双精度浮点数有效数字16位

(3)所能表示数的范围不同

·        单精度浮点的表示范围:-3.40E+38 ~+3.40E+38

·        双精度浮点的表示范围:-1.79E+308~ +1.79E+308

(4)在程序中处理速度不同一般来说,CPU处理单精度浮点数的速度比处理双精度浮点数快。

比如浮点数a.bbbbbbb* 2^ c (a=1), x.yyyyyyyy* 10^n(也可表示为x.yyyyyyyyE n)。

 float在内存中的存储遵循IEEE 754标准。在C/C++中,float类型占4个字节即32bit 32位分成了3部分:

       符号位:共1位,第31位,表示float数的正负,即前面的 0代表正数,1代表负数。

       阶码8位,30-23位,指数 c 转化成规格化的二进制之后与127之和。

       尾数:23位,22-0位,bbbbbbb。

阶码:在机器中表示一个浮点数时需要给出指数,这个指数用整数形式表示,这个整数叫做阶码,阶码指明了小数点在数据中的位置。

移码:移码(又叫增码)是符号位取反的补码,一般用做浮点数阶码,引入的目的是为了保证浮点数的机器零为全0。

浮点数中用移码表示阶码IEEE标准中,8位阶码的偏置为127


如果阶码(指数)也用补码来表示,就会使得一个浮点数中出现两个符号位:浮点数自身的和浮点数指数部分的。这样的结果是,在比较两个浮点数大小时,无法像比较整数时一样使用简单的无逻辑的二进制比较。故而浮点数的指数部分采用了移码(无符号整数)来表示。


1、8位移码的取值范围为0~255(00000000~11111111),但在浮点数的阶码中,00000000与11111111被保留用作特殊情况,所以阶码可用范围只有1~254,总共有254个值。

2、8位有符号数取值范围为-128~+127(对应补码10000000~01111111),这里的二进制用补码表示,其中特别规定补码10000000没有原码,为-128的补码,总共有256个值。

3、如果采用偏置128,在表达+127时会产生上溢(移码11111111被保留),所以在阶码中偏置为(128-1),与此同时,在表达-127时会产生下溢(移码00000000被保留),所以阶码中去掉-127与-128,取值范围为-126~127,总共254个值。


例如:13.625在内存中的存储

       首先将13.625转化成二进制

        整数部分除2取余,直到商为0停止。最后读数时,从最后一个余数读起,一直到最前面的一个余数。

        所以13的二进制为:1101
       
小数部分乘2取整,然后从前往后读。

         0.625*2 = 1.25       取整      1

         0.25*2   = 0.5         取整      0

         0.5*2    = 1            取整       1

        所以小数部分的二进制为:101

       然后将 1101.101 B的小数点向左移至小数点前只有一个1,即左移了3

       阶码就是移动位数加上偏置,即3+127 = 130  二进制表示为:1000 0010

      符号位:0

      尾数1101.101 B,移动小数点后为1.101101 B,因为小数点前必为一,所以只需要记录小数点后面的数即可,即 101101B。


第31位,符号位  第30-23位,阶码 第22-0位,尾数
0 100 00010  101 1010 0000 0000 0000 0000

  转换成16进制后为  41 5A 00 00,即在内存中的实际存储格式(未考虑大端小端模式)。

浮点数的精度取决于尾数部分。尾数部分的位数越多,能够表示的有效数字越多。
单精度数的尾数用23位存储,加上默认的小数点前的1位1,2^(23+1) = 16777216。因为 10^7 < 16777216 < 10^8,所以说单精度浮点数的有效位数是7位。

  比如,内存中有一浮点数0  0111 1100  0100 0000 0000 0000 0000 000,

1、符号位为0,表示正数

2、阶码部分求指数。1111100B=124,124-127=-3,指数为-3.

3、1.01B *2^(-3)==1.25D * 2^(-3)==0.15625


猜你喜欢

转载自blog.csdn.net/u012308586/article/details/79624748