我们经常在科学、统计、工程等领域使用实数进行计算。Kotlin 中用于表示实数的两种基本类型是:Float
和 Double
,它们被称为浮点类型(floating-point types)。事实上,这些类型无法表示任意实数,因为它们仅支持有限位数的有效小数位(Float
为 6-7 位,Double
为 14-16 位)。此外,Double
可以表示比 Float
更广泛的数值范围。
在实际编程中,开发者多数情况下会使用 Double
类型。接下来我们会重点讨论 Double
,并推荐大家在代码挑战中也使用它。当然,下面的所有内容同样适用于 Float
类型。
浮点数的算术运算
创建一个 Double
类型的变量非常简单:
val one = 1.0
val negNumber = -1.75
val pi = 3.1415
解释:这里我们创建了三个
Double
类型的变量,分别代表 1.0、-1.75 和圆周率近似值 3.1415。
如果你想创建一个 Float
类型的变量,可以这样写:
val b: Float = 8.75f
val e = 2.71828f
解释:
Float
类型的字面量必须加后缀f
。否则,它会被推断为Double
。
使用 Double
类型进行四则运算也很容易:
val number = one + 1.5 // 2.5
val c = b + negNumber // 7.0,类型为 Double,根据上下文推断
val squaredPi = pi * pi // 9.86902225
解释:
-
number
为Double
类型变量,结果是 2.5; -
c
中b
是Float
,但由于与Double
类型negNumber
相加,结果提升为Double
; -
squaredPi
是圆周率平方,约为 9.869。
对于小数,使用 /
运算符进行正常除法(非整数除法):
println(squaredPi / 2) // 输出 4.934511125
解释:结果为浮点除法,不是取整结果。
运算误差
请注意:浮点数运算可能会产生不精确的结果:
println(3.3 / 3) // 输出 1.0999999999999999
解释:虽然我们期望的结果是 1.1,但实际输出却是一个近似值,这是由于浮点数在二进制表示中存在精度限制。
多个运算会累积误差:
val num = 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1
println(num) // 输出 0.9999999999999999
解释:期望结果是 1.0,但实际是一个非常接近 1.0 的数,误差在运算中逐渐积累。
读取浮点数
你可以使用 readln()
从标准输入读取浮点数:
val f = readln().toFloat() // Float
val d = readln().toDouble() // Double
解释:
readln()
返回字符串,调用.toFloat()
或.toDouble()
方法可将其转换为相应类型。
示例:计算三角形面积
下面是一个程序,它读取三角形的底边和高,计算面积:
fun main() {
val base = readln().toDouble()
val height = readln().toDouble()
val area = (base * height) / 2
println(area)
}
解释:
-
首先读取两个
Double
值; -
然后计算
(底边 × 高度) / 2
,输出结果。
输入示例 1:
3.3
4.5
输出示例 1:
7.425
输入示例 2:
2.2
4.01
输出实例二
4.4110000000000005
解释:尽管数学结果是 4.411,但计算机的浮点精度限制使得结果为 4.4110000000000005。
小数点分隔符
使用正确的小数点符号非常重要。它依赖于语言环境(Locale),比如默认使用点号 .
作为小数点。
如果你使用了其他字符(如逗号 ,
),程序可能会报错。如果你使用的是非美式环境,但想强制使用点号,可以如下写:
import java.util.Locale
val floatNum = readln().format(Locale.US).toFloat()
总结
在本节中,我们讨论了 Kotlin 中的两种主要浮点类型:Float
和 Double
。它们都可以用于进行浮点数的运算。不过要注意以下几点:
-
浮点数可能会产生不精确的结果;
-
使用时要注意小数点的分隔符(尤其是在非英文语言环境中);
-
通常推荐使用
Double
类型来完成计算任务。