Kotlin中整数与浮点数除法为何导致温度转换结果不同?
整数运算与浮点数运算导致温度转换结果差异的原因及底层原理
问题重现
原始Kotlin代码
fun main() { printFinalTemperature(27.0, "Celsius", "Fahrenheit") { 9/5 * it + 32 } printFinalTemperature(350.0, "Kelvin", "Celsius") { it - 273.15 } printFinalTemperature(10.0, "Fahrenheit", "Kelvin") { 5.0 / 9.0 * (it - 32) + 273.15 } } fun printFinalTemperature( initialMeasurement: Double, initialUnit: String, finalUnit: String, conversionFormula: (Double) -> Double ) { val finalMeasurement = String.format("%.2f", conversionFormula(initialMeasurement)) // two decimal places println("$initialMeasurement degrees $initialUnit is $finalMeasurement degrees $finalUnit.") }
原始运行结果
27.0 degrees Celsius is 59.00 degrees Fahrenheit.
350.0 degrees Kelvin is 76.85 degrees Celsius.
10.0 degrees Fahrenheit is 260.93 degrees Kelvin.
修改9/5为9.0/5.0后的运行结果
27.0 degrees Celsius is 80.60 degrees Fahrenheit.
350.0 degrees Kelvin is 76.85 degrees Celsius.
10.0 degrees Fahrenheit is 260.93 degrees Kelvin.
核心问题
为何将整数运算9/5改为浮点数运算9.0/5.0后,温度转换结果会发生变化?底层原理是什么?
原因与底层原理
1. Kotlin整数除法的截断特性
在Kotlin(以及多数主流编程语言)中,两个整数进行除法运算时,会执行截断式取整——只保留结果的整数部分,直接丢弃小数部分。
9/5中,两个操作数都是Int类型,计算结果为1(9÷5的实际值是1.8,截断小数后仅保留整数1)。- 代入摄氏转华氏的公式后,实际计算逻辑是
1 * 27.0 + 32 = 59.0,这就是第一个结果的由来。
2. 浮点数除法的精确性
当把操作数改为9.0和5.0时,它们的类型变为Double(浮点数类型),此时执行的是浮点数除法:
9.0/5.0的结果是精确的1.8,不会截断小数部分。- 代入公式后计算逻辑为
1.8 * 27.0 + 32 = 80.6,和正确的摄氏转华氏数学结果一致。
3. 运算顺序与类型转换的影响
需要注意运算优先级和类型转换的顺序:
- 在
9/5 * it中,会先执行9/5的整数除法得到Int类型的1,再将这个整数自动提升为Double类型的1.0,最后和it(Double类型)相乘,全程损失了小数精度。 - 而
9.0/5.0 * it中,先执行浮点数除法得到Double类型的1.8,直接和it相乘,没有精度损失。
内容的提问来源于stack exchange,提问作者hakim
相关产品推荐
相关产品推荐

