008_浮点数误差问题
一、浮点数
a):float类型又被称作单精度类型,尾数可以精确到7位有效数字,在很多情况下,float类型的精度很难满足需求。
b):double表示这种类型的数值精度是float类型的两倍,又被称作双精度,绝大部分应用程序都采用double类型。
二、浮点数的表述范围
类型 |
占用存储空间 |
表数范围 |
float |
4字节 |
-3.403E38~3.403E38 |
double |
8字节 |
-1.798E308~1.798E308 |
三、在java中表示浮点数的两种表示形式
a):十进制形式 如:3.14 314.0 0.314
b):科学记数法形式 如: 314e-2 3.14e2 314E-3
四、测试浮点数代码:
public class TestFloadAndDoubleType { public static void main(String[] args) { /* [X]因为浮点数默认是double类型、而float f=0.1中0.1默认是double类型的、 这样的话将一个8个字节的double类型转换为4个字节的float类型会出现编译错误 为了明确其类型我们在后面加f */ //float a=0.1;//[X]错误的 float b=0.1f;//[√]加f来明确其类型、正确的 //浮点数可以用科学计数法来表示 double c=314e-2;//3.14 double d=314e-3;//0.314 System.out.println("double c=314e-2中c的执行结果为: c="+c); System.out.println("double d=314e-3中d的执行结果为: d="+d); //浮点数的比较(注意:浮点数运算结果比较存在误差问题、所以不能精确比较) double e=1.0/10; //0.1 System.out.println("浮点数运算结果误差示例:0.1f==1.0/10其比较结果为:"+(b==e)); float d1 = 423432423f; float d2 = d1+1; /** * 二进制表示浮点数误差问题 */ System.out.println("d1="+d1); System.out.println("d2="+d2); System.out.println("423432423f==423432423f+1的比较结果为: "+(d1==d2));//天呐尽然误差到相当? } }
测试结果为:
五、总结
a):浮点数的默认类型为double类型
b):浮点类型float, double的数据类型不适合在不允许有舍入误差的金融计算领域
c):由于浮点数占用存储空间有限,所以能够精确表示的数是有限的,因而也是离散的。浮点数一般都存在舍入误差,很多数字无法精确表示,其结果只能是接近,但不等于。
d):二进制浮点数不能精确的表示0.1,0.01,0.001这样10的负次幂。并不是所有的小数都能可以精确的用二进制浮点数表示。
e):如果需要进行不产生舍入误差的精确数字计算大小数使用BigDecimal类、大整数BigInteger
注意:通过以上我们对浮点类型的了解、我们应该避免编程中使用浮点类型进行的运算结果的比较