float计算丢精度_为什么Java float和double运算会丢失精度?

在java开发中,你也许会遇到浮点数时会丢失精度,那么先看看例子。

double a=3.00;

double b=2.10;

double c=a-b;

System.out.println("c="+c);

c=0.8999999999999999

float e=3.00f;

float f=2.10f;

float g=e-f;

System.out.println("g="+g);

g=0.9000001

显然这结果都不是我们想要的。

82b3d7ebc61f3b6af1f6f569fd3db573.png

为什么浮点型运算为什么会造成精度丢失?

在计算机中,保存这个数使用的是浮点表示法,分为三大部分:

第一部分用来存储符号位(sign),用来区分正负数,这里是0,表示正数

第二部分用来存储指数(exponent),这里的指数是十进制的6

第三部分用来存储小数(fraction),这里的小数部分是001110011

bb46360f86fcafed531be7c0ed287179.png

比如float类型是32位,是单精度浮点表示法:

符号位(sign)占用1位,用来表示正负数,

指数位(exponent)占用8位,用来表示指数,

小数位(fraction)占用23位,用来表示小数,不足位数补0。

9b59d17a47bcbbe04415d35bd651a301.png

而double类型是64位,是双精度浮点表示法:

符号位占用1位,指数位占用11位,小数位占用52位。

指数位决定了大小范围,因为指数位能表示的数越大则能表示的数越大。

而小数位决定了计算精度,因为小数位能表示的数越大,则能计算的精度越大。

f580b3ff1b627dfb0639433b38a0d4b4.png

注意:

  • 程序中应尽量避免浮点数的比较
  • float、double类型的运算往往都不准确
a8252d94a2a48c22adc0d663f4e087ec.png

解决方法:

使用BigDecimal提供的方法进行比较或运算,但要注意在构造BigDecimal的时候使用float、double的字符串形式构建,BigDecimal(String val);

运算以减法为例:

BigDecimal a1 = new BigDecimal(Double.toString(a));

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

double c1 = a1.subtract(b1).doubleValue();

System.out.println("c1="+c1);

c1=0.9

BigDecimal e1 = new BigDecimal(Float.toString(e));

BigDecimal f1 = new BigDecimal(Float.toString(f));

float g1 = e1.subtract(f1).floatValue();

System.out.println("g1="+g1);

g1=0.9

显然0.9才是我们想要的结果。

f340be2eb1d7152656ca628a6fce61bd.png
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值