浮点数整数转换精度丢失问题

浮点数转换精度丢失

在线支付对接,支付商(微信、支付宝、银联等)的接口中,定义的金额单位不一样,有时候需要对分、元进行相互转换,转换的过程中容易出现问题。

下面的例子,系统中接收的参数是元,请求接口单位是分,在转换过程中出现精度丢失,少扣了用户 1 分钱。

1
2
3
4
5
6
7
public class Main {
public static void main(String[] args) {
System.out.println((int) (0.29*100));
}
}

输出: 28

  • 错误原因

0.29*100 = 28.999999999999996…

浮点数强制转换成整数类型会舍弃非整数部分

  • 解决方法

(int) Math.round(0.29*100) -> 29

浮点数大小比较错误

1
2
3
4
5
6
7
8
9
10
// 例子 1
System.out.println(0.1d == 0.1f); // false
// 例子 2
System.out.println(10.222222225f == 10.222222229f); // true
System.out.println(10.222222225f > 10.222222229f); // false
System.out.println(10.222222225f < 10.222222229f); // false
// 例子 3
Double a = Double.valueOf("0.0");
Double b = Double.valueOf("-0.0");
System.out.println(a.equals(b)); // false

浮点数由于精度问题,并不能用 ==,>,< 来进行大小比较,最好的方式就是定义一个精度,用差的绝对值比较,在精度范围内就认为是相等的

官方文档参考

Java中的浮点数比较 == equals 和 compare