0x00:前言

  • Lua 5.2及其之前版本中,所有的数值都以双精度浮点格式表示
  • 从Lua 5.3版本开始,Lua的数值格式提供俩种格式选择

    • integer:64位整型
    • float:双精度浮点类型
  • 而在对于资源受限的平台,Lua还提供有Small Lua模式(即为将Lua 5.3编译为精简模式)

    • 在该模式下Lua的数值提供 32位整型单精度浮点类型
    • 精简模式除了使用LUA_32BITS宏定义以外,源码上其他内容与标准Lua是一致的
    • 精简模式除了在数值占用的字节大小不一致以外,其他都是与标准Lua一样的

0x01:数值常量

  • 在Lua中,无论是整型数值还是浮点型数值,都认为是number类型
    number
  • 由于整型值与浮点型值的类型都是number,所以它们是可以互相转换的;同时,具有相同算术值的整型值与浮点型值在Lua中是相等的
    值相等
  • 当然,如果需要区分整型值与浮点型值时,可以通过Lua提供math.type函数区分
    math.type
  • Lua语言与其他语言一样也支持以0x开头的十六进制常量。
    但与其他语言不同的是,Lua还支持十六进制的浮点数;这种浮点数由小数部分以及以pP开头的指数部分组成

十六进制浮点数

  • 在Lua语言中,可以使用%a参数,通过函数string.format对上述进行格式化输出
    格式化输出

0x02:算术运算

  • 在Lua语言中,除了简单的加、减、乘、除、取负等常见算术运算以外,还支持取整除法、取模和指数运算
  • 如果俩个数值类型都是整型,那么运算的结果依旧是整型,反之亦然
  • 当然,当俩个数值之间有一个是整型,一个是浮点型时,Lua在进行运算之前,会先将整型数值转换为浮点型数值,再进行运算
    运算
  • 不过,在Lua的除法不遵循上述的规则。为了避免俩个整型值相除和俩个浮点型值相除导致不一样的结果,Lua的除法运算操作的结果永远都是浮点型值
    Lua除法

    • 在Lua 5.3,针对整数除法引入了floor除法,floor除法会将得到的结果进行去尾取整。当然,floor除法遵循上面的运算规则
      floor除法
  • Lua同样也支持幂运算,使用^表示。和除法一致,幂运算后的结果也只会是浮点型

0x03:关系运算

Lua语言提供了下列关系运算

<    >    <=    >=    ==    ~=

这些关系运算的结果都是Boolean类型

  • 特别地,==用于相等性判断,~=用于不等性判断。这俩个运算符可以应用于任意俩个值,当这俩个值的类型不相同时,Lua会认为它们是不相等的
    不等判断
  • 在比较数值时,Lua会忽略数值的子类型,数值究竟是整型还是浮点型,Lua并不关心,它只关心数值的算术值

0x04:数学库

Lua提供了标准数学库math,由以下标准的数学函数组成

  • 三角函数(sin、cos、tan、asin等)

    • 所有的三角函数都是以弧度为单位,并通过degrad函数进行角度与弧度的转换
  • 指数函数(exp、pow、sqrt、log等)
  • 取整函数(floor、ceil、modf)
  • 最大最小值函数(max、min)
  • 随机数函数(random)
  • 常量pi
  • huge(最大可表示的值)

随机数发生器

在Lua中,使用math.random函数来生成伪随机数,有三种调用方式

  • 不带参调用:随机返回一个伪随机的[0,1)的数
  • 带一个整型参调用:返回一个[1,n]的伪随机整数
  • 带俩个整型参调用:返回一个[n,m]的伪随机整数

math.random

  • 注意:在Lua 5.3之后,参数一定要整型,否则会报错

在Lua中,使用math.randomseed函数来设置伪随机数发生器的种子

  • 在Lua 5.4之前的版本,Lua在启动时,系统会固定使用 1 作为种子初始化伪随机数发生器。如果不设置为其他的种子,则每次程序启动时,都会生成相同的伪随机数序列
    lua53

为了解决这个问题,通常调用math.randomseed(os.time())来使用当前系统时间作为种子初始化随机数发生器

  • 而在Lua 5.4版本之后,则不需要考虑
    lua54

取整函数

Lua的数学库中提供了三种取整函数

  • floor:向下取整
  • ceil:向上取整
  • modf:向 0 取整

当取整的结果能够用整型表示时,返回结果为整型数值,否则返回浮点型数值

取整函数

modf函数除了返回取整后值作为第一个值以外,还会返回小数部分作为第二个值

modf函数

0x05:数值表示范围

大多数编程语言使用某些固定长度的比特位来表达数值。因此,数值的表示在范围和精度上都是有限制的

对于整型数值

  • 标准Lua使用64个比特位来存储整型值,其最大值为$ 2^{63} -1$,约等于$ 10^{19} $
  • 精简Lua使用32个比特位来存储整型值,其最大值约为20亿

在数学库中的常量定义了整型值的最大值math.maxinteger与最小值math.mininteger

  • 当我们在整型操作时出现比math.maxinteger更大的值或者比math.mininteger更小的值时,就会出现回环
    回环

对于浮点型数值

  • 标准Lua使用双精度,使用64个比特位表示所有数值,其中11位为指数,范围从$ -10^{308} $到$ 10^{308} $
  • 精简Lua使用单精度,使用32个比特位,大致具有7个有效十进制位,范围从$ -10^{38} $到$ 10^{38} $

由于整型值与浮点型值的表示范围不同,因此当超过它们的表示范围时,整型值与浮点型值的算术运算结果会产生不同的结果

数值类型转换

在Lua中,可以简单的使用整型值加上0.0来将整型值转换为浮点型值,但是这样的转换在数值大于$ 2^53 $后会导致精度损失

整型转换为浮点型

将浮点型值转为整型值则有俩种方式来进行强制转换

  • 通过与零进行按位或运算
    与零按位或运算
  • 调用函数math.tointeger
    math.tointeger

但是如果输入的数值不能被转换为整型值时,函数则会返回nil
转换失败

0x06:运算符优先级

Lua语言中的运算符优先级

^
-    #    ~    not    -- 一元运算符
*    /    //    %
+    -
..                -- 连接
<<    >>            -- 按位移位
&                -- 按位与
~                -- 按位异或
|                -- 按位或
<    >    <=    >=    ~=    ==
and
or

0x07:参考文献

  • 《Lua程序设计(第4版)》
Last modification:April 5th, 2021 at 06:20 pm
给狐宝打点钱⑧