【Lua学习】数值number和数学库math

发布于:2024-10-12 ⋅ 阅读:(8) ⋅ 点赞:(0)

类型显示

Lua中number表示数值,无论是整数、浮点数、指数、负数,都用number表示。在Lua5.3以后,Lua 为数值格式提供了两种子类型,分别是 integer 的 64 位整型和 float 的双精度浮点型值。

所有的数值使用type函数都能获得相同的结果,也就是number。而想知道该数值是整型还是浮点型,则需要使用math库的type函数。

> type(-3)        -> number
> type(3.0)       -> number
> math.type(-3)   -> integer
> math.type(3.0)  -> float

算数运算

1.整数间运算

在Lua中,整数与整数相加、相减、相乘,结果为整数;相除,结果为浮点数。

> math.type(3+5) --> math.type(8)   --> integer
> math.type(3-5) --> math.type(-2)  --> integer
> math.type(3*5) --> math.type(15)  --> integer
> math.type(3/5) --> math.type(0.6) --> float

2.整数与浮点数的运算

在Lua中,整数与浮点数进行运算,结果为浮点数。

> math.type(3.0+5) --> math.type(8.0)  --> float
> math.type(3.0-5) --> math.type(-2.0) --> float
> math.type(3.0*5) --> math.type(15.0) --> float
> math.type(3.0/5) --> math.type(0.6)  --> float

3.浮点数间运算

浮点数与浮点数进行运算,结果为浮点数(不举例了)。

4.特殊除法//

Lua使用//来表示特殊除法,类似于C或C++的整数除法,整数和整数相除,结果还是整数,会向负无穷取整到最接近的整数。

> 45 // 11 -> 4
> 3.0 // 2 -> 1.0

5.取模运算

Lua进行取模运算,使用%。其中a % b 相当于 a – ((a // b) * b)。

> 45 % 11                 --> 1
> 45 - ((45 // 11) * 11)  --> 1
Tips:巧妙保留小数

有时我们需要保留小数点后n位,使用取模运算即可完成。

> x = 3.1415926
> x - x % 0.01  --> 3.14
> x - x % 0.001 --> 3.141

6.幂运算

Lua使用^表示幂运算。要注意,幂运算的结果永远是浮点数

> 4 ^ 2     --> 16.0  --计算平方
> 4 ^ 0.5   -->  2.0  --计算平方根
> 27 ^ (1/3) --> 3.0  --计算立方根

关系运算

关系运算,就是小于(<)、大于(>)、小于等于(<=)、大于等于(>=)、等于(==)、不等于(~=)。

需要注意的是,两个值类型不同,就是不等,不考虑子类型(整型和浮点型)。

> 3 < 5   --> true
> 3 > 5   --> false
> 3 < = 5 --> true
> 3 > = 5 --> false
> 3 == 5  --> false
> 3 ~= 5  --> true

数学库math

说是math库,其实只是一个名为math的表。这个库提供了基本的数学函数,它将所有函数和常数放在math表内。

常用计算

求绝对值math.abs (x)

返回x和-x之间的最大值。

> math.abs(-3.6) --> 3.6
> math.abs(3.6)  --> 3.6
求余数math.fmod (x, y)

返回x除以y的余数,该余数将商四舍五入到零。

> math.fmod(4, 3) --> 1
> math.fmod(4, 3.5) --> 0.5
> math.fmod(4.5, 3.5) --> 1.0
求对数math.log (x [, base])

返回以给定底数为base的x的对数。默认情况下,base是e(因此函数返回x的自然对数)。

> math.log(4, 2) --> 2.0
求e的x次幂math.exp (x)

返回e的x次幂(其中e是自然对数的底数)。

> math.exp(1) --> 2.718281828459
求平方根math.sqrt (x)

返回x的平方根。(你也可以使用表达式x^0.5来计算这个值。)

> math.sqrt(4) --> 2.0

三角函数

获得πmath.pi

获得π值。

> math.pi --> 3.1415926535898
角度转弧度math.rad (x)

将角度从度转换为弧度。

> math.rad(30) --> 0.5235987755983  --将角度30度转换为弧度。1度=π/180
弧度转角度math.deg (x)

将角度x从弧度转换为度。

> math.deg(0.5235987755983) --> 30.0 --将弧度0.5235987755983转换为角度。1弧度=180/π
求正弦值math.sin (x)

返回x的正弦值,以弧度为单位。

> math.sin(math.rad(30)) --> 0.5  --将30度角先转换成弧度,再求正弦值
求余弦值math.cos (x)

返回x的余弦值,以弧度为单位。

> math.cos(math.rad(60)) --> 0.5 --将60度角先转换成弧度,再求余弦值
求正切值math.tan (x)

返回x的正切值(假设x是以弧度为单位)。

> math.tan(math.rad(45)) --> 1.0 --将45度角先转换成弧度,再求正切值
求反正弦值math.asin (x)

返回x的反正弦值,以弧度为单位。

> math.deg(math.asin(0.5)) --> 30.0 --求0.5的反正弦值,再将结果转换成角度
求反余弦值math.acos (x)

返回x的反余弦值,以弧度为单位。

> math.deg(math.acos(0.5)) --> 60.0 --求0.5的反余弦值,再将结果转换成角度
求反正切值math.atan (y [, x])

返回y的反正切值,以弧度为单位。其中x是可选的,默认值为1。y代表对边,x代表斜边,如果不传入x,y相当于y/x。使用x和y两个参数的符号来确定结果的象限。它也能正确处理y为零的情况。

> math.deg(math.atan(1.0)) --> 45.0--求1.0的反正切值,再将结果转换成角度

取整函数

向正无穷取整math.ceil (x)

返回大于或等于x的最小整数值。

> math.ceil(3.3) -> 4
> math.ceil(-3.3) -> -3
向负无穷取整math.floor (x)

返回小于或等于x的最大整数值。

> math.floor(3.3) -> 3
> math.floor(-3.3) -> -4
向零取整math.modf (x)

返回x的整数部分和小数部分。它的第二个结果始终是一个浮点数。

math.modf(3.3) -> 3	0.3
math.modf(-3.3) -> -3 -0.3
math.modf(3) -> 3	0.0
math.modf(-3) -> -3	0.0

最大最小值

获得浮点数的最大值math.huge

一个大于任何其他数值的浮点值,C语言中的HUGE_VAL。

> math.huge --> inf --inf代表infinite,无穷的意思。
获得整数最大值math.maxinteger

返回整数的最大值。

> math.maxinteger --> 9223372036854775807
获得整数的最小值math.mininteger

返回整数的最小值。

> math.mininteger --> -9223372036854775808

TIPS:

--最大值加1等于最小值
> math.maxinteger + 1 == math.mininteger -> true
--最小值减1等于最大值
> math.mininteger - 1 == math.maxinteger -> true
--负最小值等于正最小值
> -math.mininteger == math.mininteger -> true
--最小值除以-1等于最小值
> math.mininteger // -1 == math.mininteger -> true
--最小值转换16进制,比最大值大1
> string.format("0x%x", math.mininteger) --> 0x8000000000000000
--最大值转换16进制,比最小值小1
> string.format("0x%x", math.maxinteger) --> 0x7fffffffffffffff
求最大值math.max (x, …)

返回一组数值的最大值。

> math.max (10, 50, 60, 30, 20, 70, 80, 40) --> 80
求最小值math.min (x, …)

返回一组数值的最小值。

> math.min(10, 50, 60, 30, 20, 70, 80, 40) --> 10

随机数

求随机值math.random ([m [, n]])

当不带参数调用时,返回一个在区间[0,1)内具有均匀分布的伪随机浮点数。

> math.random() --> 0.32537081887154

当使用两个整数m和n调用时,返回一个在区间[m, n]内具有均匀分布的伪随机整数。

> math.random(1, 10) --> 6

对于正整数n,调用math.random(n)等同于调用math.random(1,n)。

> math.random(5) --> 3

调用math.random(0)会产生一个所有位都是(伪)随机的整数。此函数使用xoshiro256**算法来生成伪随机64位整数,这些整数是带参数0的调用的结果。其他结果(范围和浮点数)是从这些整数中无偏提取的。
Lua使用相当于不带参数调用math.randomseed的方式来初始化其伪随机生成器,因此math.random应该每次程序运行时都能生成不同的结果序列。

> math.random(0) --> -7073313417451957552
> math.random(0) --> 2110367830168838180
求随机种子math.randomseed ([x [, y]])

当至少带一个参数调用时,整数参数x和y被合并成一个128位的种子,用于重新初始化伪随机生成器;相同的种子会产生相同的数字序列。y的默认值是零。
当不带参数调用时,Lua会生成一个种子,其中包含对随机性的微弱尝试。
此函数返回实际使用的两个种子组件,因此再次设置它们将重复序列。
为了确保初始状态达到所需的随机性水平(或者相反,为了有一个确定性的序列,例如在调试程序时),你应该使用明确的参数调用math.randomseed。

一般使用os.time()作为种子。

> math.randomseed(os.time()) --> 1726496864	0

其它

转换整数math.tointeger (x)

如果值x可以转换为整数,则返回该整数。否则,返回失败。

> math.tointeger(3.0) --> 3
> math.tointeger("3.0") -->3
> math.tointeger("55ff") --> nil
获得类型math.type (x)

如果x是整数,则返回”integer”;如果x是浮点数,则返回”float”;如果x不是数字,则返回fail。

> math.type(3) --> integer
> math.type(3.0) --> float
> math.type("3") --> nil
math.ult (m, n)

如果m和n以无符号整数进行比较时,m < n,那么返回true,否则返回false。

> math.ult(2,3)  --> true
> math.ult(-2,3) --> false
TIPS: math.ult(-2,3) –> false

在 Lua 中,math.ult(m, n) 函数比较两个整数的无符号值。当使用 math.ult(-2, 3) 时,结果将是 false。这是因为当 -2 和 3 被视为无符号整数时,它们的二进制表示如下:

-2 在32位系统中通常表示为 0xFFFFFFFE(因为它是 0x00000002 的二进制补码表示,取反加一)。

3 在32位系统中表示为 0x00000003。

在无符号比较中,0xFFFFFFFE(即 -2 的无符号表示)实际上是一个非常大的正整数,因为它在内存中的位模式表示的是一个大于 0x7FFFFFFF(即32位系统中的最大有符号整数值)的数。而 0x00000003 是一个相对较小的正整数。
因此,0xFFFFFFFE(无符号的 -2)大于 0x000000033),所以 math.ult(-2, 3) 返回 false