Java中double类型货币金额拆分面值的浮点数精度问题咨询
问题根因
你遇到的精度问题是double类型的固有缺陷:double基于二进制存储,0.1、0.05这类十进制小数无法被精确表示,多次加减运算后误差会不断累积,就会出现0.1变成0.099999964这类问题,货币计算场景禁止直接使用double做算术运算。
另外你的代码重复逻辑过多,每一个面额都单独写变量计算,后续调整面额非常麻烦。
最优修复方案
核心思路是把所有金额转换为最小面额的整数单位进行计算:你需求里的最小面额是0.001,直接把输入金额乘以1000后四舍五入转成long型整数,所有面额也同步转换为整数单位,全程用整数运算完全避免精度问题。同时把面额存入数组遍历计算,代码量大幅减少,后续调整面额只需要修改数组即可。
import java.util.Scanner; public class CurrencySplit { public static void main(String[] args) { Scanner input = new Scanner(System.in); // 按从大到小顺序定义面额:[换算为最小单位0.001的整数值, 显示用的面额度] Object[][] denominations = { {200000, "200"}, {100000, "100"}, {50000, "50"}, {20000, "20"}, {10000, "10"}, {5000, "5"}, {1000, "1"}, {500, "0.5"}, {250, "0.25"}, {100, "0.1"}, {50, "0.05"}, {1, "0.001"} }; // 输入金额转最小单位整数,用round消除浮点转换误差 long totalAmount = Math.round(input.nextDouble() * 1000); for (Object[] denom : denominations) { int unit = (int) denom[0]; String faceValue = (String) denom[1]; int count = (int) (totalAmount / unit); // 不需要输出0张的可以打开下面一行的注释 // if (count == 0) continue; System.out.println(count + "---" + faceValue); totalAmount = totalAmount % unit; } input.close(); } }
内容的提问来源于stack exchange,提问作者Selçuk
相关产品推荐
相关产品推荐

