您的位置:首页 > 理论基础

浮点数介绍及使用注意事项

2017-03-14 22:26 281 查看
浮点数基本知识

计算机中的浮点数占4个字节,由三部分组成:

Sign(1bit):表示浮点数是正数还是负数。0表示正数,1表示负数
Exponent(8bits):指数部分。类似于科学技术法中的M*10^N中的N,只不过这里是以2为底数而不是10。需要注意的是,指数部分有正指数和负指数,因此以127表示指数为0,即01111111代表2^0,因此转换时需要根据127作偏移调整。
Mantissa(23bits):基数部分。是浮点数具体数值规格化之后的实际表示。

以5.2为代表来看看浮点数的转化过程:

(1)先将十进制数用二进制数表示出来。

整数部分5表示成101.。小数部分0.2=2^-3+2^-4+2^-7+2^-8+...,表示成二进制是.001100110011001100110011...。合在一起,就是101.0011001100110011...。

(2)规格化二进制数。

将上步中得到的二进制数改写成小数点前面只有一位数的形式,相当于科学计数法,101.0011001100110011可以改写为1.010011001100110011*2^2。这样就完成了规格化。

(3)填充。

将规格化的二进制数填充到浮点数的三部分中。这里,指数部分是2,根据127做偏移之后就是129,即10000001。基数部分在填充时,将整数部分舍去,因为规格化后的整数部分总是1,因此基数部分填充的内容是01001100110011001100110。

最后整个浮点数的计算机表示为:0 10000001 01001100110011001100110。

了解完浮点数的表达以后,不难看出浮点数的精度和指数范围有很大关系。最低不能低过2^-7-1最高不能高过2^8-1(其中剔除了指数部分全0喝全1的特殊情况)。如果超出表达范围那么不得不舍弃末尾的那些小数,我们成为overflow和underflow。甚至有时舍弃都无法表示,例如当我们要表示一个:1.00001111*2^-7这样的超小数值的时候就无法用规格化数值表示,如果不想点其他办法的话,CPU内部就只能把它当做0来处理。

浮点数使用注意事项

精确计算时不要使用float和double

浮点数乍一看好像能得到很精确的值,其实不然。计算机中存储浮点数其实是在一个很广的值域内提供了一个近似值,并不能提供精确的值,如我们上面讲到的5.2这个数,因为它不能将0.1或者任何10的负次幂表示为一个有限长度的二进制小数,因此二进制浮点数对于精确计算时非常不适合的。

比如我们执行System.out.println(1.03-0.42),输出的结果是0.6100000000000001,结尾多出的1就是近似计算的结果。

需要精确计算时,推荐使用BigDecimal。(java.math.BigDecimal类)

上面的计算用BigDecimal来计算如下所示:

BigDecimal income = new BigDecimal("1.03");

BigDecimal expense= new BigDecimal("0.42");

System.out.println(income.substrate(expense));

对于加减乘除,BigDecimal提供的成员方法分别是:

public BigDecimal add(BigDecimal value);                        //加法
public BigDecimal subtract(BigDecimal value);                   //减法
public BigDecimal multiply(BigDecimal value);                   //乘法
public BigDecimal divide(BigDecimal value);                     //除法


进行相应的计算后,我们可能需要将BigDecimal对象转换成相应的基本数据类型的变量,可以使用floatValue(),doubleValue()等方法。

循环变量不能为浮点数

原因是浮点数的表示范围有限,且不是精确表示,当超出浮点数表示范围时,循环条件可能无法进行下去。

如for(int i=2000000000;i<2000000050;i++),系统认为2000000000=2000000050,无法开始循环。

判断两个浮点数是否相等不能直接使用==

原因:由于浮点数在计算机表示中存在精度问题

可以采取如下的方式进行判断:
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  计算机基础