浮点类型与精度丢失

1.浮点类型的存储

float存储需求是4字节(32位), 其中1位最高位是符号位,中间8位表示阶位,后32位表示值

double存储需求是8字节(64为),其中1位最高位是符号位,中间11位表示阶位,后52位表示值

如下图所示:

double 表示这种类型的数值精度是 float 类型的两倍(有人称之为双精度数值)。绝大部
分应用程序都采用 double 类型。在很多情况下,float 类型的精度很难满足需求。实际上,只
有很少的情况适合使用 float 类型,例如,需要单精度数据的库, 或者需要存储大量数据。
float 类型的数值有一个后缀 F 或 f (例如, 3.14F)。没有后缀 F 的浮点数值(如 3.14 ) 默
认为 double 类型。当然,也可以在浮点数值后面添加后缀 D 或 d (例如,3.14D)。
 

2.浮点数类型的精度丢失

public class SimpleTest {
    public static void main(String[] args) {
    	System.out.println(1.2 - 1);
    }
}

该代码块输出为

0.19999999999999996

而非预料中的0.2。

产生的原因是二进制表示十进制小数产生的问题

十进制0.2转换为2进制的过程为:

0.2 * 2 = 0.4 取整数部分 0

0.4 * 2 = 0.8 取整数部分 0

0.8 * 2 = 1.6 取整数部分 1

0.6 * 2 = 1.2 取整数部分 1

0.2 * 2 = 0.4 取整数部分 0

……

过程是一个无限循环。

0.2的2进制从上到下可以表示为 00110011......,小数的二进制表示有时是不可能精确的,正如十进制小数无法准确表示1/3,二进制也无法准确表示1/5。

精度丢失就是我们有限的存储位置无法容纳有时无限的二进制小数。

3.精度丢失的解决

浮点数值不适用于无法接受舍入误差的金融计算中。 例如,命令 System.out.println
( 2.0-1.1 ) 将打印出 0.8999999999999999, 而不是人们想象的 0.9。这种舍入误差的主要
原因是浮点数值采用二进制系统表示, 而在二进制系统中无法精确地表示分数 1/10。 这
就好像十进制无法精确地表示分数 1/3
就应该使用 BigDecimal类。

代码演示:

public static void main(String[] args) {
		   BigDecimal b1 = new BigDecimal(Float.toString(1.2f));
		   BigDecimal b2 = new BigDecimal(Float.toString(1));
		   float s = b1.subtract(b2).floatValue(); 
		   System.out.println("s----" + s);
}


 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值