神奇的浮点数-容易产生精度的浮点数

在计算机中,浮点数容易产生精度问题的主要原因是它们在底层采用二进制表示,而某些十进制小数无法用二进制有限位精确表示。这种误差会在存储和运算中累积。以下是容易导致精度问题的浮点数类型和场景:


1. 无法用二进制精确表示的十进制小数

在这里插入图片描述


2. 小数位过多的数值

  • 如果浮点数的小数位较多,超出了浮点数格式(如 IEEE 754)的精度范围,存储时会进行截断或舍入。
  • IEEE 754 的双精度浮点数(double)仅有 52 位尾数部分,单精度浮点数(float)只有 23 位尾数部分。

例如:

  • ( 0.1234567890123456789 ) 在 double 中会被截断为 ( 0.12345678901234568 )。

3. 特别大的或特别小的浮点数

  • 浮点数使用科学计数法存储,大范围的指数会导致 尾数的有效位数损失(即精度下降)。
    • 特别大的数:小数部分可能被忽略。
    • 特别小的数:可能被近似为 ( 0 )(称为 下溢)。

例如:

  • ( 1.000000000000001 \times 10^{20} + 1 ) 可能被近似为 ( 1.000000000000001 \times 10^{20} )。

4. 浮点数的运算累积误差

  • 浮点运算的每一步都可能引入微小误差,经过多次运算后误差可能累积放大。
    • 例如:反复加减 ( 0.1 ) 时,误差会逐步累积。

示例:

System.out.println(0.1 + 0.2); // 输出:0.30000000000000004

5. 浮点数比较

  • 由于浮点数的精度问题,直接用 == 比较浮点数可能得不到预期结果。
    • 例如:
      System.out.println(0.1 + 0.2 == 0.3); // 输出:false
      

6. 特别的问题场景

  1. 货币计算:

    • 浮点数不适合进行货币相关计算,因为货币计算需要精确到分甚至更小的单位。
    • 建议使用 BigDecimal 或整数(以最小单位存储,如“分”而不是“元”)。
  2. 几何计算:

    • 几何计算中使用浮点数进行长度、角度或坐标计算时,精度问题可能导致结果偏差。
  3. 循环结构中的累计:

    • 在循环中反复叠加小的浮点数时(例如求和),误差会逐渐累积。

总结

容易产生精度问题的浮点数包括:

  • 无法用二进制精确表示的十进制小数(如 ( 0.1, 0.3 ))。
  • 小数位较多的数值(超过精度范围)。
  • 特别大的或特别小的数值(导致舍入或下溢)。
  • 涉及多步计算或累积操作的数值

避免方案

  • 使用整数或 BigDecimal(如处理货币或需要精确计算时)。
  • 避免直接比较浮点数,使用误差范围(如 (|a - b| < \epsilon))。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值