Kotlin:根据金额实现货币单位Quarter的复数化处理
代码问题分析与优化方案
原代码的核心问题
你的代码存在几个明显的错误和不合理之处:
- 单复数逻辑完全颠倒:语法规则是1个用"Quarter",≥2个用"Quarters",但你的代码中
quarters <=2输出"Quarters",quarters>2输出"Quarter",比如1个时会错误输出"Quarters",4个时输出"Quarter",完全不符合要求。 - quarters计算逻辑错误(巧合得正确值):Quarter是0.25美元,正确计算应该是总金额除以0.25取整数部分。你当前用
Math.floor(changeDue /1.0)的逻辑根本不对,示例中1.22的结果正确只是巧合,换个金额比如0.5,你的代码会算出0个quarters,完全错误。 - Double处理金额有精度隐患:浮点数无法精确表示所有十进制小数,比如0.29这类金额,用Double计算会出现精度误差,导致quarters数量计算错误。
- 硬编码剩余金额:直接输出".22 remain"不是动态计算的,换个金额就会出错。
- 不符合Kotlin编码规范:函数名应小写开头(
Change改成change),变量名需更清晰(比如quarters改成numberOfQuarters)。
优化后的实现方式
方式1:用整数(美分为单位)处理金额(推荐)
彻底避免浮点数精度问题,将金额转为整数(比如1.22美元=122美分),计算更准确:
fun main(args: Array<String>) { val changeDueInCents = 122 // 1.22美元对应122美分 calculateChange(changeDueInCents) } fun calculateChange(changeDueInCents: Int) { val quarterValueInCents = 25 val numberOfQuarters = changeDueInCents / quarterValueInCents val remainingCents = changeDueInCents % quarterValueInCents // 输出数量与单复数 print(numberOfQuarters) println(if (numberOfQuarters == 1) " Quarter" else " Quarters") // 动态输出剩余金额 println("${remainingCents / 100.0} remain") }
方式2:用BigDecimal处理浮点数精度
如果必须用小数表示金额,用BigDecimal规避精度误差:
import java.math.BigDecimal import java.math.RoundingMode fun main(args: Array<String>) { val changeDue = BigDecimal("1.22") calculateChange(changeDue) } fun calculateChange(changeDue: BigDecimal) { val quarterValue = BigDecimal("0.25") val numberOfQuarters = changeDue.divide(quarterValue, 0, RoundingMode.FLOOR).toInt() val remaining = changeDue.subtract(quarterValue.multiply(BigDecimal(numberOfQuarters))) print(numberOfQuarters) println(if (numberOfQuarters == 1) " Quarter" else " Quarters") println("$remaining remain") }
关键优化点
- 修正单复数逻辑:仅当数量为1时用"Quarter",其余情况用"Quarters"(若需处理0的情况,可单独加判断)。
- 修正金额计算逻辑:基于Quarter实际价值(0.25美元/25美分)计算数量,而非错误的除以1.0。
- 解决精度问题:用整数或BigDecimal替代Double,避免浮点数计算误差。
- 动态计算剩余金额:通过总金额减去已使用的Quarter金额得到剩余值,而非硬编码。
- 遵循编码规范:函数名、变量名符合Kotlin命名约定。
内容的提问来源于stack exchange,提问作者Lynn
相关产品推荐
相关产品推荐

