如何在C#找零程序中按规则设置小数部分取值?
解决C#找零计算中50分硬币的小数部分处理问题
直接用double处理货币会有精度误差,这大概率是你用if语句判断失败的原因——比如0.25可能被存储为0.2499999999999999,导致判断逻辑失效。以下是两种可靠的解决方法:
方法一:用整数(便士)处理,彻底避免浮点误差
把金额转换为便士(1英镑=100便士),用整数运算来判断和计算,完全规避精度问题:
// 示例输入:商品价格、付款金额 double itemPrice = 12.30; double payment = 20.00; double change = payment - itemPrice; // 转换为整数便士,用Round避免浮点转换误差 int totalPence = (int)Math.Round(change * 100); int fractionalPence = totalPence % 100; // 提取小数部分对应的便士数 int adjustedFractional = 0; // 按照规则调整小数部分 if (fractionalPence < 25) { adjustedFractional = 0; } else if (fractionalPence > 25 && fractionalPence < 75) { adjustedFractional = 50; } else if (fractionalPence > 75) { adjustedFractional = 100; } // 计算调整后的总便士数,注意小数部分满100要进位到整数部分 int adjustedTotalPence = (totalPence / 100) * 100 + adjustedFractional; if (adjustedFractional == 100) { adjustedTotalPence += 100; } // 计算50分(halfCrown)硬币数量 int halfCrownCount = adjustedTotalPence / 50; adjustedTotalPence %= 50; // 输出结果 Console.WriteLine($"调整后找零金额:{adjustedTotalPence / 100.0 + (halfCrownCount * 0.5):C}"); Console.WriteLine($"50分硬币数量:{halfCrownCount}"); // 可继续添加其他纸币/硬币的计算逻辑
方法二:用数学取整简化逻辑
如果不想用整数处理,也可以用Math.Round直接对找零金额按0.5的步长取整,一步实现规则:
double itemPrice = 12.30; double payment = 20.00; double change = payment - itemPrice; // 按0.5步长取整:小于0.25舍为0,0.25-0.75取0.5,大于0.75进为1 double adjustedChange = Math.Round(change * 2) / 2; // 计算50分硬币数量 int pounds = (int)adjustedChange; double fractionalPart = adjustedChange - pounds; int halfCrownCount = fractionalPart >= 0.5 ? 1 : 0; // 输出结果 Console.WriteLine($"调整后找零金额:{adjustedChange:C}"); Console.WriteLine($"50分硬币数量:{halfCrownCount}");
注意事项
- 永远不要用
double直接存储或计算货币金额,推荐使用decimal类型,它专为高精度十进制运算设计,能避免大部分精度问题:
用decimal itemPrice = 12.30m; decimal payment = 20.00m; decimal change = payment - itemPrice;decimal的话,方法一和方法二的逻辑同样适用,且精度更可靠。
内容的提问来源于stack exchange,提问作者Sand
相关产品推荐
相关产品推荐

