java中float与double精度问题

一、float与double介绍

我们使用数据的时候都是使用十进制的方式进行运算,然而在计算机中数据存储都是使用二进制的方式。
我们通过使用十进制进行小数点存储运算时,数据是可以精准展示,但是在进行二进制转换后得出的数据因精度问题就不能精确展示。

1、float与double的区别
  1. 在内存中占有的字节数不同
    单精度浮点数在机内占4个字节,32位,首位表示符号,8位表示阶数k,剩下表示尾数部分。
    双精度浮点数在机内占8个字节,64位,首位表示符号,11位表示阶数k,剩下表示尾数部分。
  2. 有效数字位数不同
    单精度浮点数有效数字8位
    双精度浮点数有效数字16位
  3. 所能表示数的范围不同
    单精度浮点的表示范围:-(2-2-23) * 2127 到(2-2-23) * 2127
    双精度浮点的表示范围:-(2-252)* 21024到(2-2-52) * 21024
2、float数据存储规则
  1. float共占四个字节,64bit,1bit为符号位,8bit为指数位,23bit为尾数位
  2. 第1个bit为符号位,0表示正数,1表示负数
  3. 第2-9个bit为指数位,表示范围为(0-255),使用补码需要减去127,取值范围为(-127到128),二进制全0与全1有特殊含义,最终取值范围为(-126到127)
  4. 第10到32bit为尾数,float类型的精度有此处决定,在规格化表示时,前导有个默认值1,因此可以表示24位
  5. 规格化表示:指数位数值为-126到127之间,数据范围为-2127到2127
  6. 非规格化表示:当指数部分全0而且小数部分不全0时表示的是非规格化的浮点数,因为这里默认没有前导1,而是0,指数全为0表示2-126,加上尾数可以表示最小的数为2-149
  7. 特殊情况:
    A、当指数部分和小数部分全为0时,表示0值,有+0和-0之分(符号位决定),0x00000000表示正0,0x80000000表示负0.
    B、指数部分全1,小数部分全0时,表示无穷大,有正无穷和负无穷,0x7f800000表示正无穷,0xff800000表示负无穷.
    C、指数部分全1,小数部分不全0时,表示NaN,分为QNaN和SNaN,Java中都是NaN
3、小数的十进制与二进制表示

十进制表示方式:4.567=4 * 100 + 5 * 10-1 + 6 * 10-2 + 7 * 10-3
二进制表示方式:10.5=1 * 23 + 1 * 21 + 1 * 2-1
float与double引起精度问题,考虑是不同进制下数据转化存在转化不完整导致,如果需要在商业系统中计算价钱,最好使用BigDecimal类

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Javafloatdouble都是用二进制浮点数表示的,它们的精度是有限的。因为二进制浮点数无法精确表示某些十进制数,如0.1,所以在进行精确计算时需要特别注意。 在进行浮点数计算时,可以使用BigDecimal类来实现精确计算。BigDecimal类可以表示任意精度的十进制数,而且支持加、减、乘、除等基本的数学运算。 下面是一个使用BigDecimal类进行浮点数计算的例子: ``` import java.math.BigDecimal; public class FloatDoublePrecision { public static void main(String[] args) { float f1 = 0.1f; float f2 = 0.2f; double d1 = 0.1; double d2 = 0.2; BigDecimal b1 = new BigDecimal(Float.toString(f1)); BigDecimal b2 = new BigDecimal(Float.toString(f2)); BigDecimal b3 = new BigDecimal(Double.toString(d1)); BigDecimal b4 = new BigDecimal(Double.toString(d2)); BigDecimal result1 = b1.add(b2); BigDecimal result2 = b3.add(b4); System.out.println("Float计算结果:" + result1); System.out.println("Double计算结果:" + result2); } } ``` 输出结果如下: ``` Float计算结果:0.300000011920928955078125 Double计算结果:0.3000000000000000444089209850062616169452667236328125 ``` 可以看到,使用floatdouble进行计算得到的结果都存在精度问题。而使用BigDecimal类进行计算可以得到精确的结果。 需要注意的是,使用BigDecimal类进行计算时需要使用字符串形式的构造方法,而不能直接使用浮点数进行构造,否则仍然会存在精度问题

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值