您的位置:首页 > 编程语言 > Java开发

Java学习之double类型数据比较

2017-06-14 09:41 295 查看

Java学习之double类型数据比较

对于两个double类型的数据,是不能直接用==来比较是否相等

double a=1.01;
double b=1.01;
if(b==a){
System.out.println("相等");
}


上面的代码是不会在控制台打印信息的

double a=1.01;
double b=1.01;
System.out.println(b==a);


上面的代码在控制台打印出false

下面介绍两种比较double数据是否相等的方法。

1. 转换成字符串之后用equals方法比较

2. 转换成Long之后用==方法比较

double a=1.01;
double b=1.01;
System.out.println(String.valueof(b)==String.valueof(a));
System.out.println(Double.doubleToLongBits(a)==Double.doubleToLongBits(b));


之所以要避免double,float之间的运算原因如下:

1. float和double是java的基本类型,用于浮点数表示,在java中float占4个字节32位,double占8个字节64位,一般比较适合用于工程测量计算中,其在内存里的存储结构如下:

float:

符号位(1 bit)

指数(8 bit)

尾数(23 bit)

double:

符号位(1 bit)

指数(11 bit)

尾数(52 bit)

注意:从左到右是从低位到高位,而在计算机内部是采用逆序存储的。

2. System.out.println(2.00-1.10);中的1.10不能被计算机精确存储,以double类型数据1.10举例计算机如何将浮点型数据转换成二进制存储,

这里重点讲小数部分转换成二进制:

1.10整数部分就是1,转换成二进制1(这里整数转二进制不再赘述)

小数部分:0.1

0.1*2=0.2取整数部分0,基数=0.2

0.2*2=0.4取整数部分0,基数=0.4

0.4*2=0.8取整数部分0,基数=0.8

0.8*2=1.6取整数部分1,基数=1.6-1=0.6

0.6*2=1.2取整数部分1,基数=1.2-1=0.2

0.2*2=0.4取整数部分0,基数=0.4

.

.

.

.

直至基数为0。1.1用二进制表示为:1.000110…xxxx….(后面表示省略)

0.1 = 0*2^(-1)+0*2^(-2)+0*2^(-3)+1*2^(-4)+………而double类型表示小数部分只有52位,当向后计算 52位后基数还不为0,那后面的部分只能舍弃,从这里可以看出float、double并不能准确表示每一位小数,对于有的小数只能无限趋向它。在计算机 中加减成除运算实际上最后都要在计算机中转换成二进制的加运算,由此,当计算机运行System.out.println(2.00-1.10);

时会拿他们在计算机内存中的二进制表示计算,而1.10的二进制表示本身就不准确,所以会出现0.8999999999999999的结果。

但为什么System.out.println(2.00f-1.10f);得出的结果是0.9呢。因为float精度没有double精度那么大,小数部分0.1二进制表示被舍去的比较多。

注意:

程序中应尽量避免浮点数的比较

float、double类型的运算往往都不准确

解决方法:

使用BigDecimal提供的方法进行比较或运算,但要注意在构造BigDecimal的时候使用float、double的字符串形式构建,BigDecimal(String val);为什么不用BigDecimal(double val)API里写的比较清楚。

运算以减法为例:

BigDecimal b1 = new BigDecimal(Double.toString(2.00));

BigDecimal b2 = new BigDecimal(Double.toString(1.10));

double result = b1.subtract(b2).doubleValue();
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java