数据类型讲解及面试扩展

1.java的进制表示:

在这里插入图片描述

2.float和double精度丢失及解决办法

2.1float和double精度丢失

public class test1 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
           float f = 0.1f;
           double d = 1.0/10;
           System.out.println(f == d);//false
           System.out.println(f);     //0.1
           System.out.println(d);     //0.1
           
           float d1 = 23232323232323f;
           float d2 = d1+1;
           System.out.println(d1 == d2);//true
	}
}

f 和 d 都等于0.1,但是比较后却不相等;d2 比 d1 多 1,但是比较后却相等。
这是因为float精度丢失原因。
float 关键词: 离散  舍入误差  有限  大约  接近但不等于

重要的事情说3遍:
最好完全避免使用浮点数进行比较
最好完全避免使用浮点数进行比较
最好完全避免使用浮点数进行比较


2.2解决办法:

BigDecimal
public BigDecimal(double val)
将 double 转换为 BigDecimal,后者是 double 的二进制浮点值准确的十进制表示形式。返回的 BigDecimal 的标度是使 (10scale × val) 为整数的最小值。
注:

   1.此构造方法的结果有一定的不可预知性。有人可能认为在 Java 中写入 new BigDecimal(0.1) 所创建的 BigDecimal 正好等于 0.1(非标度值 1,其标度为 1),但是它实际上等于 0.1000000000000000055511151231257827021181583404541015625。这是因为 0.1 无法准确地表示为 double(或者说对于该情况,不能表示为任何有限长度的二进制小数)。这样,传入 到构造方法的值不会正好等于 0.1(虽然表面上等于该值)。
   2.另一方面,String 构造方法是完全可预知的:写入 new BigDecimal(“0.1”) 将创建一个 BigDecimal,它正好 等于预期的 0.1。因此,比较而言,通常建议优先使用 String 构造方法。
   3.当 double 必须用作 BigDecimal 的源时,请注意,此构造方法提供了一个准确转换;它不提供与以下操作相同的结果:先使用 Double.toString(double) 方法,然后使用 BigDecimal(String) 构造方法,将 double 转换为 String。要获取该结果,请使用 static valueOf(double) 方法。


解决方法:

相信从上面的文档大家也已经找出了解决方法,

在需要精确的表示两位小数时我们需要把他们转换为BigDecimal对象,然后再进行运算。

另外需要注意

使用BigDecimal(double val)构造函数时仍会存在精度丢失问题,建议使用BigDecimal(String val)

这就需要先把double转换为字符串然后在作为BigDecimal(String val)构造函数的参数。转换为BigDecimal对象

之后再进行加减乘除操作,这样精度就不会出现问题了。这也是为什么有关金钱数据存储都使用BigDecimal。

public void testBig(){
    System.out.println(0.11+2001299.32);//非精确的输出
    BigDecimal bigDecimal1 = new BigDecimal(Double.toString(0.11));
    BigDecimal bigDecimal2 = new BigDecimal(Double.toString(2001299.32));
    System.out.println(bigDecimal1.add(bigDecimal2));//精确的输出
}

控制台输出:

2001299.4300000002
2001299.43

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值