PHP中如何新增或延续while循环处理小于1的找零?
找零计算完整解决方案
先修正原代码里的bug,再添加硬币找零的逻辑,同时解决浮点精度问题:
原代码的问题
- 处理20美元纸币时,输出错误用了
$bills50output变量,应该是$bills20output - 直接用
(int)($change*100)转整数分会有浮点精度误差,比如0.19美元可能被转成18分 - 缺少硬币找零的处理逻辑
修正后的完整代码
<?php $total_cost = (float)$_POST['total_cost']; $amount_provided = (float)$_POST['amount_provided']; $change = $amount_provided - $total_cost; // 处理纸币部分(≥1美元) if ($change >= 1) { $billItems = []; while ($change >= 1) { if ($change >= 50) { $count = (int)($change / 50); $billItems[] = "$count 张50美元纸币"; $change -= $count * 50; } elseif ($change >= 20) { $count = (int)($change / 20); $billItems[] = "$count 张20美元纸币"; $change -= $count * 20; } elseif ($change >= 10) { $count = (int)($change / 10); $billItems[] = "$count 张10美元纸币"; $change -= $count * 10; } elseif ($change >= 5) { $count = (int)($change / 5); $billItems[] = "$count 张5美元纸币"; $change -= $count * 5; } elseif ($change >= 1) { $count = (int)$change; $billItems[] = "$count 张1美元纸币"; $change -= $count; } } // 格式化纸币输出,解决标点和连接词问题 $lastBill = array_pop($billItems); $billOutput = implode(', ', $billItems); echo $billOutput ? "你将获得 $billOutput,以及 $lastBill。<br>" : "你将获得 $lastBill。<br>"; } // 处理硬币部分(<1美元,转成整数分避免浮点误差) $cents = round($change * 100); if ($cents > 0) { $coinItems = []; // 定义硬币面额和对应描述 $coins = [ 50 => '50分硬币', 25 => '25分硬币', 10 => '10分硬币', 5 => '5分硬币', 1 => '1分硬币' ]; foreach ($coins as $value => $name) { if ($cents >= $value) { $count = (int)($cents / $value); $coinItems[] = "$count 个$name"; $cents -= $count * $value; } } // 格式化硬币输出 $lastCoin = array_pop($coinItems); $coinOutput = implode(', ', $coinItems); echo $coinOutput ? "另外,你将获得 $coinOutput,以及 $lastCoin。" : "另外,你将获得 $lastCoin。"; } elseif ($change < 0) { echo "金额不足,还差 " . abs($change) . " 美元。"; } else { echo "无需找零。"; } ?>
核心改进点
- 精度修复:用
round()把美元小数转成整数分,避免浮点运算导致的误差 - 代码简化:把输出内容先存进数组,最后统一格式化,不用反复判断单复数和标点
- 逻辑清晰:硬币部分用数组定义面额,循环处理,后续要调整面额直接改数组就行
- bug修复:修正了20美元纸币输出的变量错误
- 边界处理:加了金额不足和无需找零的提示
内容的提问来源于stack exchange,提问作者GalacticLux
相关产品推荐
相关产品推荐

