除了 加
、 减
、 乘
、 除
、 取负数
、 单目减法
(即把减号当做一元运算符使用)等常见的算数运算外, Lua
语言还支持 取整除法
、 float除法
、 取模
和 指数
运算。
对于 Lua5.3
中引入的整型而言,主要的建议就是:开发人员要么选择忽略整型和浮点型二者之间的不同,要么就完整的控制每一个数值的表示。因此,所有的算数操作符不论操作整型值还是浮点型值,结果都应该是一样的。
算数运算结果类型
两个整型值进行 相加
、 相减
、 相乘
、 相除
和 取负
操作的结果仍然是整型值。对于这些算数运算而言,操作数是用整型还是浮点型表示的整数都没有区别(除非发生溢出)。
> 13 + 15 --> 28 > 13.0 + 15.0 --> 28.0
如果两个操作数都是整型值,那么结果也是整型值,否则,结果就是浮点型值。
当操作数一个是整型值,一个是浮点型值时, Lua
语言会在进行算数运算前先将整型值转换为浮点型值。
> 13.0 + 25 --> 38.0 > -(3 * 6.0) --> -18.0
除法运算
由于两个整数相除的结果并不一定是整数(数学领域成为不能整除),因此除法不遵循上述规则。为了避免两个整型值相除和两个浮点型值相除导致不一样的结果,除法运算操作的永远是浮点数且产生浮点型值的结果。
> 3.0 / 2.0 --> 1.5 > 3 /2 --> 1.5
Lua5.3
针对整数除法引入一个称为 floor除法
的新运算符—— //
。顾名思义,floor除法会对得到的商向负无穷取整,从而保证结果是一个整数。这样,floor除法就可以与其他算数运算一样遵循同样的规则:如果两个操作数都是整型值,那么结果就是整型值,否则就是浮点型值。
> 3 // 2 --> 1 > 3.0 // 2 --> 1.0 > 6 // 2 --> 3 > 6.0 // 2.0 --> 3.0 > -9 // 2 --> -5 > 1.5 // 0.5 --> 3.0
取模运算
以下公式是取模运算的定义:
a % b == a - ((a // b) * b)
如果操作数是整数,那么取模运算的结果也是整数。因此,取模运算也遵从与算数运算相同的规律,即如果两个操作数都是整型值,那么结果就是整型值,否则就是浮点型值。
对于整型操作数而言,取模运算的含义没什么特别的,其结果的符号永远与第二个操作数的符号保持一致。特别的,对于任意指定的正常量K,即使 x
是负数,表达式 x%K
的结果也永远在 [0, K-1]
之间。例如,对于任意整型值 i
,表达式 i%2
的结果均是 0
或 1
。
对于实数类型的操作数而言,取模运算有一些不同。例如: x-x%0.01
恰好是 x
保留两位小数的结果, x-x%0.001
恰好是 x
保留三位小数的结果。
> x = math.pi > x - x%0.01 --> 3.14 > x - x%0.001 --> 3.141
再比如,我们可以使用取模运算检查某车辆再拐过了指定的角度后是否能够原路返回。假设使用度作为角度的单位,可以使用如下公式:
local tolerance = 10 function isTurnBak (angle) angle = angle % 360 return (math.abs(angle - 180) < tolerance) end
该函数对于负的角度而言也同样适用:
print(isTurnBak(-180)) --> true
假设使用弧度作为角度的单位,只需要简单的修改常量定义即可:
local tolerance = 0.17 function isTurnBak (angle) angle = angle % (2*math.pi) return (math.abs(angle - math.pi) < tolerance) end
表达式 angule%(2*math.pi)
实现了将任意范围的角度归一化到 [0, 2π)
之间。
幂运算
Lua
语言同样支持幂运算,使用符号 ^
表示。像除法一样,幂运算的操作数也永远是浮点类型(整型值在幂运算是不能整除,例如:2^{-2}2−2的结果不是整型值)。我们可以使用 x^0.5
来计算 x
的平方根,使用 x^(1/3)
来计算 x
的立方根。