写在前面:
在实习公司写了一个传感器的驱动程序,传感器数据有时会出现异常值,有时正常。把计算过程的临时变量由整形定义为double类型后异常值不再出现。后来定位到出错原因,是因为整形(32位)临时变量溢出,解决方法是计算时把临时变量强制类型转换为范围较大的整形(64位),或者直接用64位整形。
用double类型之所以不会出错,是因为double类型计算时都自动转为double类型了。double类型表示范围大,不存在溢出问题。其实用float也不会出问题。
下面说一下float和double类型。
float和double分别称为单精度和双精度浮点型,它们的区别如下:
单精度浮点数(float)与双精度浮点数(double)的区别如下:
(1)在内存中占有的字节数不同
· 单精度浮点数在机内占4个字节
· 双精度浮点数在机内占8个字节
(2)有效数字位数不同
(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
今天的文章float和double类型介绍分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/8773.html