Skip to content

Math 数学库使用说明 ​

📖 模块概述 ​

Math数学库提供了丰富的数学函数和常量,包括三角函数、对数函数、随机数生成等。这些函数是进行数值计算和科学计算的基础工具。

主要功能 ​

  • 🔢 基本数学运算
  • 📐 三角函数计算
  • 📊 对数和指数函数
  • 🎲 随机数生成
  • 📏 数值处理函数
  • 🔣 数学常量

适用场景 ​

  • 科学计算
  • 工程计算
  • 游戏开发
  • 数据分析
  • 算法实现

📚 API参考 ​

📋 函数列表 ​

函数名功能描述示例
📏 math.abs(x)绝对值math.abs(-5) → 5
📐 math.acos(x)反余弦math.acos(0) → 1.5708
📐 math.asin(x)反正弦math.asin(1) → 1.5708
📐 math.atan(x)反正切math.atan(1) → 0.7854
📐 math.atan2(y, x)⚠ 仅固件,模拟器无 —— 改用 math.atan(y, x)math.atan(1, 1) → 0.7854
📈 math.ceil(x)向上取整math.ceil(3.2) → 4
📐 math.cos(x)余弦math.cos(0) → 1
🔁 math.deg(x)弧度转角度math.deg(math.pi) → 180
📈 math.exp(x)e的x次方math.exp(1) → 2.7183
📉 math.floor(x)向下取整math.floor(3.8) → 3
📊 math.fmod(x, y)浮点取模math.fmod(7, 3) → 1
📊 math.log(x, [base])对数math.log(10, 10) → 1
🔝 math.max(x, ...)最大值math.max(1, 5, 3) → 5
🔝 math.min(x, ...)最小值math.min(1, 5, 3) → 1
🔢 math.modf(x)分离整数和小数部分math.modf(3.14) → 3, 0.14
📈 math.pow(x, y)⚠ 仅固件,模拟器无 —— 改用 x ^ ymath.pow(2, 3) → 8
🔁 math.rad(x)角度转弧度math.rad(180) → 3.1416
🎲 math.random([m, n])随机数math.random(1, 10) → 1-10
🎲 math.randomseed(x)设置随机种子math.randomseed(123)
📐 math.sin(x)正弦math.sin(0) → 0
📐 math.sqrt(x)平方根math.sqrt(16) → 4
📐 math.tan(x)正切math.tan(0) → 0

📏 数学常量 ​

📏 math.pi ​

圆周率π

值: 3.141592653589793

示例:

lua
print(math.pi)                    -- 3.141592653589793
print(2 * math.pi)               -- 6.283185307179586 (2π)

-- 计算圆的面积
local function circle_area(radius)
    return math.pi * radius * radius
end

print(circle_area(5))             -- 78.539816339744831

📏 math.huge ​

正无穷大

示例:

lua
print(math.huge)                  -- inf
print(math.huge > 1000000)       -- true
print(math.huge == math.huge)    -- true

-- 用作初始值
local min_value = math.huge
local max_value = -math.huge

📈 math.abs(x) ​

绝对值

参数:

  • x (number): 数值

返回值:

  • number: 绝对值

示例:

lua
print(math.abs(-5))               -- 5
print(math.abs(3.14))             -- 3.14
print(math.abs(0))                -- 0

-- 计算两点间距离
local function distance(x1, y1, x2, y2)
    return math.sqrt(math.abs(x2-x1)^2 + math.abs(y2-y1)^2)
end

实用例程 ​

lua
	  --print("send",buffer,getTime)
	  send_buffer=encoder.to16hex(buffer)
	  com1:send(send_buffer)
	  recv=com1:recv()	
	  --getTime = os.date("%Y-%m-%d %H:%M:%S");
	  print("recv:"..encoder.from16hex(recv))			

	  if string.sub(recv, 1, 3)==encoder.to16hex("<设备ID或凭据>")  then
		v = string.sub(recv, 4, 5)
		old = plc.d(4)
		plc.d(4,tonumber(encoder.from16hex(v),16)+600)
		v_stata = 0
	  else		
		v_stata = v_stata+1	
	  end				
	  plc.d(5,v_stata)				

	  --		print("D04 ",plc.d(4))
	  --		print("D05 ",plc.d(5))

	  if math.abs(plc.d(4)-old) >v_time or plc.d(4)>2900 or  plc.d(4)<1900   then
		system.sleep(10000)
		v_time =2			
	  else
		system.sleep(60000)	
		v_time =10					
	  end
	  --print("co1 run")--打印输出
	end
  end
)


co2=coroutine.create(function()--建立协程2
	--数据上传
	x=mqtt.creat("192.168.1.100", 1883, "<名称>", "<名称>", "<名称>")--建立 MQTT 对象
	x:start()--启动 MQTT 协议栈

	dssc=timer.start(60000,
	  function()--启动定时器 60 秒发布一个数据

把上面的地址、主题、引脚替换成你项目里的即可。

📈 math.ceil(x) / 📉 math.floor(x) ​

向上取整 / 向下取整

参数:

  • x (number): 数值

返回值:

  • number: 取整后的值

示例:

lua
print(math.ceil(3.2))             -- 4
print(math.ceil(-3.2))            -- -3
print(math.floor(3.8))            -- 3
print(math.floor(-3.8))           -- -4

-- 价格计算
local function round_up_price(price)
    return math.ceil(price * 100) / 100  -- 向上取整到分
end

print(round_up_price(12.341))     -- 12.35

实用例程 ​

lua
--以下为凉水井电站(核定流量0.12m3/s、测量渠深度0.3米*宽度0.7米),投入式生态流量程序
wzgd= -0.13 --安装高度(出水槽底为0,低于为-高于为+)在安装时按实际输入
b=0.7--明渠宽度: 米
g=9.81  --单位 :m/s2	
ds1=timer.start(5000,function()
		--local sw = plc.d(10) / 100   --传感器采集到的水位单位:米(传感器采集单位为cm)
		local  h = wzgd	+ (plc.d(10) / 100) --sw +
		local h1=h --后面判断真实水位是否为0
		print("<名称>",h)		
		if h <= 0 then h =0.01 end --后面公式中除数不能为
	   --if  h > 0.3 then h = 0.3 end --,超过测量渠部分不计算泄放流量
		e=h --无闸明渠 h =e  
	    u=0.6-0.176 *(e/h)--南京水利科学研究所提供经验参数  
		Q=u*b*e*(math.sqrt(2*g*h))--流量单位m3/s(水利部推荐公式)
		--Q=math.floor(Q*1000)  / 1000 --保留3位小数
		if h1 <= 0 then  Q =0.000 end --真实水位小于0后,流量置0
		print("<名称>",Q)
		plc.df(0,Q)
	end)

把上面的地址、主题、引脚替换成你项目里的即可。

🔝 math.max(x, ...) / 🔝 math.min(x, ...) ​

最大值 / 最小值

参数:

  • x, ... (number): 多个数值

返回值:

  • number: 最大值或最小值

示例:

lua
print(math.max(1, 5, 3, 9, 2))    -- 9
print(math.min(1, 5, 3, 9, 2))    -- 1

-- 限制数值范围
local function clamp(value, min_val, max_val)
    return math.max(min_val, math.min(max_val, value))
end

print(clamp(15, 10, 20))          -- 15
print(clamp(5, 10, 20))           -- 10
print(clamp(25, 10, 20))          -- 20

📈 x^y — 幂运算 ​

幂运算优先用 ^:math.pow 只有固件有,模拟器没有

两个平台的 Lua 版本与兼容开关不同,这批函数不是哪都能用:

固件(ESP32 全系)软 PLC 模拟器
Lua 版本5.4.25.5.0
LUA_COMPAT_MATHLIB(旧版 math 函数兼容开关)开关
math.pow atan2 log10 cosh sinh tanh frexp ldexp能调用nil,调用即报错

写跨平台脚本(同一段 Lua 既要下机型又要在模拟器联调)一律用 ^ 和两参数 math.atan(y, x):

lua
print(2 ^ 3)                 -- 8,两个平台都对
print(math.atan(1, 1))       -- 0.7854…,5.4 的 atan 已接受第二个参数,不要写 math.atan2

语法:

  • x ^ y — x 的 y 次幂

示例:

lua
print(2^3)                        -- 8
print(9^0.5)                      -- 3 (平方根,也可用 math.sqrt(9))

-- 复利计算
local function compound_interest(principal, rate, time)
    return principal * (1 + rate)^time
end

print(compound_interest(1000, 0.05, 10))  -- 1628.89

📐 math.sqrt(x) ​

平方根

参数:

  • x (number): 非负数

返回值:

  • number: 平方根

示例:

lua
print(math.sqrt(16))              -- 4
print(math.sqrt(2))               -- 1.4142135623731

-- 计算直角三角形斜边
local function hypotenuse(a, b)
    return math.sqrt(a*a + b*b)
end

print(hypotenuse(3, 4))           -- 5

实用例程 ​

lua
--以下为凉水井电站(核定流量0.12m3/s、测量渠深度0.3米*宽度0.7米),投入式生态流量程序
wzgd= -0.13 --安装高度(出水槽底为0,低于为-高于为+)在安装时按实际输入
b=0.7--明渠宽度: 米
g=9.81  --单位 :m/s2	
ds1=timer.start(5000,function()
		--local sw = plc.d(10) / 100   --传感器采集到的水位单位:米(传感器采集单位为cm)
		local  h = wzgd	+ (plc.d(10) / 100) --sw +
		local h1=h --后面判断真实水位是否为0
		print("<名称>",h)		
		if h <= 0 then h =0.01 end --后面公式中除数不能为
	   --if  h > 0.3 then h = 0.3 end --,超过测量渠部分不计算泄放流量
		e=h --无闸明渠 h =e  
	    u=0.6-0.176 *(e/h)--南京水利科学研究所提供经验参数  
		Q=u*b*e*(math.sqrt(2*g*h))--流量单位m3/s(水利部推荐公式)
		--Q=math.floor(Q*1000)  / 1000 --保留3位小数
		if h1 <= 0 then  Q =0.000 end --真实水位小于0后,流量置0
		print("<名称>",Q)
		plc.df(0,Q)
	end)

把上面的地址、主题、引脚替换成你项目里的即可。

📐 三角函数 ​

📐 math.sin(x) / math.cos(x) / math.tan(x) ​

正弦 / 余弦 / 正切

参数:

  • x (number): 弧度值

返回值:

  • number: 三角函数值

示例:

lua
-- 角度转弧度
local function deg_to_rad(degrees)
    return degrees * math.pi / 180
end

print(math.sin(deg_to_rad(30)))   -- 0.5
print(math.cos(deg_to_rad(60)))   -- 0.5
print(math.tan(deg_to_rad(45)))   -- 1

-- 计算圆上的点
local function point_on_circle(center_x, center_y, radius, angle_deg)
    local angle_rad = deg_to_rad(angle_deg)
    local x = center_x + radius * math.cos(angle_rad)
    local y = center_y + radius * math.sin(angle_rad)
    return x, y
end

local x, y = point_on_circle(0, 0, 10, 45)
print(x, y)  -- 7.071, 7.071

📐 math.asin(x) / math.acos(x) / math.atan(x) ​

反三角函数

参数:

  • x (number): 函数值

返回值:

  • number: 弧度值

示例:

lua
-- 弧度转角度
local function rad_to_deg(radians)
    return radians * 180 / math.pi
end

print(rad_to_deg(math.asin(0.5)))  -- 30
print(rad_to_deg(math.acos(0.5)))  -- 60
print(rad_to_deg(math.atan(1)))    -- 45

-- 计算向量角度(Lua 5.4 没有 math.atan2,用两参数的 math.atan(y, x))
local function vector_angle(x, y)
    return rad_to_deg(math.atan(y, x))
end

print(vector_angle(1, 1))          -- 45

📊 对数函数 ​

📊 math.log(x, [base]) ​

对数

参数:

  • x (number): 真数
  • base (number, 可选): 底数,默认为e

返回值:

  • number: 对数值

示例:

lua
print(math.log(math.exp(1)))      -- 1 (自然对数)
print(math.log(100, 10))          -- 2 (常用对数)
print(math.log(8, 2))             -- 3 (以2为底)

-- 计算信息熵
local function entropy(probabilities)
    local h = 0
    for _, p in ipairs(probabilities) do
        if p > 0 then
            h = h - p * math.log(p, 2)
        end
    end
    return h
end

print(entropy({0.5, 0.5}))        -- 1.0

📈 math.exp(x) ​

指数函数 (e^x)

参数:

  • x (number): 指数

返回值:

  • number: e的x次幂

示例:

lua
print(math.exp(0))                -- 1
print(math.exp(1))                -- 2.718281828459 (e)
print(math.exp(2))                -- 7.3890560989307

-- 正态分布概率密度函数
local function normal_pdf(x, mean, std_dev)
    local variance = std_dev * std_dev
    local coefficient = 1 / math.sqrt(2 * math.pi * variance)
    local exponent = -0.5 * ((x - mean) / std_dev)^2
    return coefficient * math.exp(exponent)
end

🎲 随机数函数 ​

🎲 math.random([m, n]) ​

生成随机数

参数:

  • 无参数: 返回[0,1)的随机数
  • m (number): 返回[1,m]的随机整数
  • m, n (number): 返回[m,n]的随机整数

返回值:

  • number: 随机数

示例:

lua
-- 基本随机数
print(math.random())              -- 0.xxx (0到1之间)
print(math.random(6))             -- 1-6 (骰子)
print(math.random(10, 20))        -- 10-20之间

-- 随机选择
local function random_choice(list)
    local index = math.random(#list)
    return list[index]
end

local colors = {"红", "绿", "蓝", "黄"}
print(random_choice(colors))

-- 洗牌算法
local function shuffle(list)
    for i = #list, 2, -1 do
        local j = math.random(i)
        list[i], list[j] = list[j], list[i]
    end
    return list
end
实用例程 ​
lua
--以下为改为水坝测量的程序2026-7-24
h_az=0.17 --安装高度m(传感器距离渠底距离)
b=1.40   --水渠宽度m
h=0.2 --水渠水度m(测量深度-安装高度)

ds=timer.start(6000,function()
	h_ss=plc.d(0)--传感器采集水深cm	
		print("<名称>",h_ss)
	h=(h_ss / 100 ) - h_az --水深度m	
	if h<=0 then h=0.01 end  
print("<名称>",h)

        g=9.81  --重力加速度,常量,单位:m/s2
        u=0.6-0.176*(h/h)--南京水利科学研究所提供经验参数    (开度与水深一样)
		
		Q=u*b*h*(math.sqrt(2*g*h))--流量单位m3/s(水利部推荐公式)
		print("Q:",Q)
		local sjs=math.random() / 100 --随机数
		if Q<0.061 then  Q = 0.062 +sjs  end  --2026-7-21临时调整搬家后重做
		print("<名称>",Q)
		plc.df(4,Q)--浮点数,单位m3/s补习班入到D4供采集终端采集;	

		
		
	end)

把上面的地址、主题、引脚替换成你项目里的即可。

🎲 math.randomseed(x) ​

设置随机数种子

参数:

  • x (number): 种子值

示例:

lua
-- 使用时间作为种子
math.randomseed(os.time())

-- 或使用固定种子以获得可重复的结果
math.randomseed(12345)
for i = 1, 5 do
    print(math.random(100))
end

🚀 使用示例 ​

示例1: 几何计算 ​

lua
-- 几何计算示例
function geometry_example()
    print("=== 几何计算示例 ===")
    
    -- 点类
    local Point = {}
    Point.__index = Point
    
    function Point:new(x, y)
        return setmetatable({x = x or 0, y = y or 0}, Point)
    end
    
    function Point:distance_to(other)
        local dx = self.x - other.x
        local dy = self.y - other.y
        return math.sqrt(dx*dx + dy*dy)
    end
    
    function Point:angle_to(other)
        local dx = other.x - self.x
        local dy = other.y - self.y
        return math.atan(dy, dx) * 180 / math.pi
    end
    
    -- 圆类
    local Circle = {}
    Circle.__index = Circle
    
    function Circle:new(center, radius)
        return setmetatable({
            center = center,
            radius = radius
        }, Circle)
    end
    
    function Circle:area()
        return math.pi * self.radius * self.radius
    end
    
    function Circle:circumference()
        return 2 * math.pi * self.radius
    end
    
    function Circle:contains_point(point)
        return self.center:distance_to(point) <= self.radius
    end
    
    -- 测试几何计算
    local p1 = Point:new(0, 0)
    local p2 = Point:new(3, 4)
    local p3 = Point:new(1, 1)
    
    print("点的坐标:")
    print(string.format("P1: (%.1f, %.1f)", p1.x, p1.y))
    print(string.format("P2: (%.1f, %.1f)", p2.x, p2.y))
    print(string.format("P3: (%.1f, %.1f)", p3.x, p3.y))
    
    print("\n距离计算:")
    print(string.format("P1到P2的距离: %.2f", p1:distance_to(p2)))
    print(string.format("P1到P3的距离: %.2f", p1:distance_to(p3)))
    
    print("\n角度计算:")
    print(string.format("P1到P2的角度: %.1f°", p1:angle_to(p2)))
    print(string.format("P1到P3的角度: %.1f°", p1:angle_to(p3)))
    
    -- 圆的计算
    local circle = Circle:new(p1, 5)
    print("\n圆的属性:")
    print(string.format("半径: %.1f", circle.radius))
    print(string.format("面积: %.2f", circle:area()))
    print(string.format("周长: %.2f", circle:circumference()))
    
    print("\n点与圆的关系:")
    print(string.format("P2在圆内: %s", circle:contains_point(p2) and "是" or "否"))
    print(string.format("P3在圆内: %s", circle:contains_point(p3) and "是" or "否"))
end

geometry_example()

示例2: 统计计算 ​

lua
-- 统计计算示例
function statistics_example()
    print("\n=== 统计计算示例 ===")
    
    -- 统计函数库
    local Stats = {}
    
    function Stats.mean(data)
        local sum = 0
        for _, value in ipairs(data) do
            sum = sum + value
        end
        return sum / #data
    end
    
    function Stats.median(data)
        local sorted = {}
        for _, value in ipairs(data) do
            table.insert(sorted, value)
        end
        table.sort(sorted)
        
        local n = #sorted
        if n % 2 == 0 then
            return (sorted[n/2] + sorted[n/2 + 1]) / 2
        else
            return sorted[math.ceil(n/2)]
        end
    end
    
    function Stats.variance(data)
        local mean = Stats.mean(data)
        local sum_sq_diff = 0
        
        for _, value in ipairs(data) do
            local diff = value - mean
            sum_sq_diff = sum_sq_diff + diff * diff
        end
        
        return sum_sq_diff / (#data - 1)
    end
    
    function Stats.std_dev(data)
        return math.sqrt(Stats.variance(data))
    end
    
    function Stats.min_max(data)
        local min_val = math.huge
        local max_val = -math.huge
        
        for _, value in ipairs(data) do
            min_val = math.min(min_val, value)
            max_val = math.max(max_val, value)
        end
        
        return min_val, max_val
    end
    
    function Stats.percentile(data, p)
        local sorted = {}
        for _, value in ipairs(data) do
            table.insert(sorted, value)
        end
        table.sort(sorted)
        
        local index = p * (#sorted - 1) + 1
        local lower = math.floor(index)
        local upper = math.ceil(index)
        
        if lower == upper then
            return sorted[lower]
        else
            local weight = index - lower
            return sorted[lower] * (1 - weight) + sorted[upper] * weight
        end
    end
    
    -- 生成测试数据
    math.randomseed(os.time())
    local test_data = {}
    
    print("生成100个随机数据点...")
    for i = 1, 100 do
        -- 生成正态分布样的数据
        local u1 = math.random()
        local u2 = math.random()
        local z = math.sqrt(-2 * math.log(u1)) * math.cos(2 * math.pi * u2)
        local value = 50 + 10 * z  -- 均值50,标准差10
        table.insert(test_data, value)
    end
    
    -- 计算统计量
    local mean = Stats.mean(test_data)
    local median = Stats.median(test_data)
    local variance = Stats.variance(test_data)
    local std_dev = Stats.std_dev(test_data)
    local min_val, max_val = Stats.min_max(test_data)
    
    print("\n描述性统计:")
    print(string.format("样本数量: %d", #test_data))
    print(string.format("均值: %.2f", mean))
    print(string.format("中位数: %.2f", median))
    print(string.format("方差: %.2f", variance))
    print(string.format("标准差: %.2f", std_dev))
    print(string.format("最小值: %.2f", min_val))
    print(string.format("最大值: %.2f", max_val))
    print(string.format("范围: %.2f", max_val - min_val))
    
    -- 百分位数
    print("\n百分位数:")
    local percentiles = {25, 50, 75, 90, 95, 99}
    for _, p in ipairs(percentiles) do
        local value = Stats.percentile(test_data, p / 100)
        print(string.format("第%d百分位: %.2f", p, value))
    end
    
    -- 数据分布分析
    print("\n数据分布:")
    local bins = {}
    local bin_width = (max_val - min_val) / 10
    
    for i = 1, 10 do
        bins[i] = {
            min = min_val + (i-1) * bin_width,
            max = min_val + i * bin_width,
            count = 0
        }
    end
    
    for _, value in ipairs(test_data) do
        for i, bin in ipairs(bins) do
            if value >= bin.min and (value < bin.max or i == #bins) then
                bin.count = bin.count + 1
                break
            end
        end
    end
    
    for i, bin in ipairs(bins) do
        local bar = string.rep("*", math.floor(bin.count / 2))
        print(string.format("[%.1f, %.1f): %2d %s", 
              bin.min, bin.max, bin.count, bar))
    end
end

statistics_example()

🔧 最佳实践 ​

1. 角度和弧度转换 ​

lua
-- 角度弧度转换工具
local MathUtils = {}

function MathUtils.deg_to_rad(degrees)
    return degrees * math.pi / 180
end

function MathUtils.rad_to_deg(radians)
    return radians * 180 / math.pi
end

-- 标准化角度到[0, 360)范围
function MathUtils.normalize_angle(degrees)
    degrees = degrees % 360
    if degrees < 0 then
        degrees = degrees + 360
    end
    return degrees
end

2. 数值比较 ​

lua
-- 浮点数比较
local function float_equal(a, b, epsilon)
    epsilon = epsilon or 1e-10
    return math.abs(a - b) < epsilon
end

-- 安全的除法
local function safe_divide(a, b)
    if math.abs(b) < 1e-10 then
        return math.huge * (a >= 0 and 1 or -1)
    end
    return a / b
end

3. 随机数工具 ​

lua
-- 随机数工具集
local Random = {}

function Random.init()
    math.randomseed(os.time())
end

function Random.float(min, max)
    return min + (max - min) * math.random()
end

function Random.normal(mean, std_dev)
    -- Box-Muller变换生成正态分布
    local u1 = math.random()
    local u2 = math.random()
    local z = math.sqrt(-2 * math.log(u1)) * math.cos(2 * math.pi * u2)
    return mean + std_dev * z
end

function Random.weighted_choice(items, weights)
    local total_weight = 0
    for _, weight in ipairs(weights) do
        total_weight = total_weight + weight
    end
    
    local random_weight = math.random() * total_weight
    local current_weight = 0
    
    for i, weight in ipairs(weights) do
        current_weight = current_weight + weight
        if random_weight <= current_weight then
            return items[i]
        end
    end
    
    return items[#items]
end

⚠️ 注意事项 ​

1. 浮点数精度 ​

  • 浮点数运算可能有精度误差
  • 比较浮点数时使用epsilon值
  • 避免直接比较浮点数是否相等

2. 三角函数 ​

  • 三角函数使用弧度制,不是角度制
  • 注意定义域限制(如asin的输入范围[-1,1])
  • 反三角函数的值域范围

3. 随机数 ​

  • 使用前设置随机数种子
  • 相同种子产生相同的随机序列
  • 随机数质量取决于实现

4. 特殊值处理 ​

  • 除零操作返回inf或-inf
  • 对负数开平方根返回NaN
  • 注意math.huge和NaN的处理

例程 ​

数学库(math.*)做量程标定、取整、随机、统计量。下面例程都是可直接下载运行的完整脚本:顶层执行完即结束,不阻塞主循环。工业里最常用的是「把 4–20mA / 0–10V 原始值换算成工程值」。

例程 1:量程线性标定(原始值 → 工程值) ​

适用:全部机型 / 软PLC模拟器 / 上位机 | 依赖模块:math plc | 难度:★☆☆

场景:AI0 读到原始 0..4095(12 位 ADC),要换算成 0..10.0V;或 4–20mA 映射成 0..100%。

完整代码(可直接下载运行):

lua
local function adc_to_volt(raw, full)
    -- raw: 0..full(4095) → 0.0..10.0 V
    return raw / full * 10.0
end

local v = adc_to_volt(2048, 4095)
print("电压 =", string.format("%.2f V", v))

-- 4-20mA → 0-100%: (raw-4)/(20-4)*100
local function ma_to_pct(raw)
    return (raw - 4) / 16 * 100
end
print("流量 =", string.format("%.1f %%", ma_to_pct(12)))

要点:

  • 标定本质是线性插值 y = (x - x0)/(x1 - x0) * (y1 - y0) + y0。
  • 用 math.floor/ceil 取整数档位;要显示几位小数用 string.format("%.2f", v)。

验证方法:

  1. 原始 2048(约半量程)应得约 5.00 V。
  2. ma_to_pct(12) = (12-4)/16*100 = 50.0%。

注意事项:

  • / 永远得浮点:3/2 是 1.5,不是 1(// 才是向下取整的整除,3//2 = 1)。 要把结果当整数用就显式 math.floor(x/y),别指望 / 自动截断。
  • 除零得 inf/-inf,标定前先判分母非零。
  • 浮点别用 == 比较,用 math.abs(a-b) < 1e-6。

例程 2:四舍五入与偏差判断 ​

适用:同上 | 依赖模块:math | 难度:★☆☆

场景:温度要显示到 0.1 度;判断「实测值与设定值偏差超过 1.0 就报警」。

完整代码(可直接下载运行):

lua
local function round(x, n)        -- 保留 n 位小数
    local p = 10 ^ n
    return math.floor(x * p + 0.5) / p
end

print(round(23.456, 1))   -- 23.5
print(round(-2.5, 0))     -- -2(注意负数向零方向)

local set, meas = 350, 352.3
if math.abs(meas - set) > 1.0 then
    print("偏差超限:", math.abs(meas - set))
else
    print("偏差正常")
end

要点:

  • math.floor(x * 10^n + 0.5) / 10^n 是通用四舍五入。
  • math.abs 取绝对值,配合阈值做「偏差/越限」判断。
  • math.max/min 可给数值限幅:v = math.max(0, math.min(100, v))。

验证方法:

  1. round(23.456,1) → 23.5;偏差 2.3 > 1.0 打印「偏差超限: 2.3」。
  2. 把 meas 改成 350.3,偏差 0.3 打印「偏差正常」。

注意事项:

  • math.floor(-2.5) = -3(向负无穷取整),所以负数「四舍五入」可能和直觉相反;要银行家舍入需另写。
  • round 用 0.5 加法定点对接近 .5 的浮点有误差,严格要求用 string.format 再 tonumber。
  • 限幅优先用 math.max/min 而非 if 嵌套,更清晰。

例程 3:随机抽检与统计量 ​

适用:同上 | 依赖模块:math | 难度:★★☆

场景:对一批产品按概率抽检;或统计一组数据的均值/最大/最小做趋势判断。

完整代码(可直接下载运行):

lua
math.randomseed(os.time())          -- 让每次运行序列不同(嵌入式可能不支持 os.time)

-- 1/10 概率抽检
if math.random() < 0.1 then
    print("本件抽检")
end

-- 统计量
local data = { 1, 5, 3, 9, 2 }
local sum, mx, mn = 0, data[1], data[1]
for _, v in ipairs(data) do
    sum = sum + v
    mx = math.max(mx, v)
    mn = math.min(mn, v)
end
print("均值", sum / #data, "最大", mx, "最小", mn)

要点:

  • math.random() → [0,1);math.random(m, n) → [m,n] 整数。
  • math.randomseed(x) 设种子;不设置每次启动序列相同。
  • math.max/min 接受多参数,适合一边遍历一边求极值。

验证方法:

  1. 多跑几次,「本件抽检」大约每 10 次出现 1 次。
  2. 统计量打印「均值 4 最大 9 最小 1」。

注意事项:

  • 嵌入式固件可能不实现 os.time()/math.randomseed,随机序列固定;需要真随机可从上位机下发种子。
  • math.random() 返回浮点,math.random(1,10) 才是整数档。
  • 求均值前确认 #data > 0,否则除零。

最后更新: 2026-04-26版本: 1.0

函数速查表 ​

下表列出本库全部函数与方法(含尚未单独成节的),点「说明」可跳转到对应小节。签名按通用记法:括号内按顺序列全参数,方括号里的可以省略(不传走默认值),... 表示还可继续传同类参数;h: 开头的是对象方法,先用库级函数拿回句柄再冒号调用。

方法与签名作用说明
math.abs(number)取绝对值本文开头
math.acos(number)反余弦(弧度)本文开头
math.asin(number)反正弦(弧度)本文开头
math.atan(number)反正切(弧度)本文开头
math.atan2(number)双参数反正切,按 x、y 求象限角跳转
math.ceil(number)向上取整本文开头
math.cos(number)余弦本文开头
math.cosh(number)双曲余弦跳转
math.deg(number)弧度转角度跳转
math.exp(number)e 的 x 次方本文开头
math.floor(number)向下取整本文开头
math.fmod(number, number)取余数跳转
math.frexp(number)把浮点数拆成尾数和 2 的指数跳转
math.huge正无穷大(比较溢出用)本文开头
math.ldexp(number, integer)尾数乘 2 的指数(frexp 的逆运算)跳转
math.log(number, number)自然对数(可给底数)本文开头
math.log10(number)以 10 为底的对数跳转
math.max(...)取最大值本文开头
math.maxinteger整数能表示的最大值跳转
math.min(...)取最小值本文开头
math.mininteger整数能表示的最小值跳转
math.modf(number)'double'.跳转
math.pi圆周率本文开头
math.pow(number, number)x 的 y 次方跳转
math.rad(number)角度转弧度跳转
math.random取随机数(可限定范围)本文开头
math.randomseed设随机数种子本文开头
math.sin(number)正弦本文开头
math.sinh(number)双曲正弦跳转
math.sqrt(number)开平方本文开头
math.tan(number)正切本文开头
math.tanh(number)双曲正切跳转
math.tointeger(...)转成整数,转不了返回 nil跳转
math.type(...)区分整数/浮点数/非数字跳转
math.ult(integer, integer)按无符号数比较 a 是否小于 b跳转

math.atan2 ​

  • 作用:双参数反正切,按 x、y 求象限角
  • 调用形态:math.atan2(number)(库级函数)
  • 参数:1 个参数:第 1 个为数值(必填)
  • 返回:1 个值
  • 可用机型:ESP32 机型 · 软 PLC 模拟器 / 上位机

math.cosh ​

  • 作用:双曲余弦
  • 调用形态:math.cosh(number)(库级函数)
  • 参数:1 个参数:第 1 个为数值(必填)
  • 返回:1 个值
  • 可用机型:ESP32 机型 · 软 PLC 模拟器 / 上位机

math.deg ​

  • 作用:弧度转角度
  • 调用形态:math.deg(number)(库级函数)
  • 参数:1 个参数:第 1 个为数值(必填)
  • 返回:1 个值
  • 可用机型:ESP32 机型 · 软 PLC 模拟器 / 上位机

math.fmod ​

  • 作用:取余数
  • 调用形态:math.fmod(number, number)(库级函数)
  • 参数:2 个参数:第 1 个为数值(必填)、第 2 个为数值(必填)
  • 返回:1 个值
  • 可用机型:ESP32 机型 · 软 PLC 模拟器 / 上位机

math.frexp ​

  • 作用:把浮点数拆成尾数和 2 的指数
  • 调用形态:math.frexp(number)(库级函数)
  • 参数:1 个参数:第 1 个为数值(必填)
  • 返回:2 个值
  • 可用机型:ESP32 机型 · 软 PLC 模拟器 / 上位机

math.ldexp ​

  • 作用:尾数乘 2 的指数(frexp 的逆运算)
  • 调用形态:math.ldexp(number, integer)(库级函数)
  • 参数:2 个参数:第 1 个为数值(必填)、第 2 个为整数(必填)
  • 返回:1 个值
  • 可用机型:ESP32 机型 · 软 PLC 模拟器 / 上位机

math.log10 ​

  • 作用:以 10 为底的对数
  • 调用形态:math.log10(number)(库级函数)
  • 参数:1 个参数:第 1 个为数值(必填)
  • 返回:1 个值
  • 可用机型:ESP32 机型 · 软 PLC 模拟器 / 上位机

math.maxinteger ​

  • 作用:整数能表示的最大值
  • 形态:math.maxinteger 不是可调用函数(不要加括号),按变量使用
  • 可用机型:ESP32 机型 · 软 PLC 模拟器 / 上位机

math.mininteger ​

  • 作用:整数能表示的最小值
  • 形态:math.mininteger 不是可调用函数(不要加括号),按变量使用
  • 可用机型:ESP32 机型 · 软 PLC 模拟器 / 上位机

math.modf ​

  • 作用:'double'.
  • 调用形态:math.modf(number)(库级函数)
  • 参数:1 个参数:第 1 个为数值(必填)
  • 返回:2 个值
  • 可用机型:ESP32 机型 · 软 PLC 模拟器 / 上位机

math.pow ​

  • 作用:x 的 y 次方
  • 调用形态:math.pow(number, number)(库级函数)
  • 参数:2 个参数:第 1 个为数值(必填)、第 2 个为数值(必填)
  • 返回:1 个值
  • 可用机型:ESP32 机型 · 软 PLC 模拟器 / 上位机

math.rad ​

  • 作用:角度转弧度
  • 调用形态:math.rad(number)(库级函数)
  • 参数:1 个参数:第 1 个为数值(必填)
  • 返回:1 个值
  • 可用机型:ESP32 机型 · 软 PLC 模拟器 / 上位机

math.sinh ​

  • 作用:双曲正弦
  • 调用形态:math.sinh(number)(库级函数)
  • 参数:1 个参数:第 1 个为数值(必填)
  • 返回:1 个值
  • 可用机型:ESP32 机型 · 软 PLC 模拟器 / 上位机

math.tanh ​

  • 作用:双曲正切
  • 调用形态:math.tanh(number)(库级函数)
  • 参数:1 个参数:第 1 个为数值(必填)
  • 返回:1 个值
  • 可用机型:ESP32 机型 · 软 PLC 模拟器 / 上位机

math.tointeger ​

  • 作用:转成整数,转不了返回 nil
  • 调用形态:math.tointeger(...)(库级函数)
  • 参数:1 个参数:第 1 个为任意(必填)
  • 返回:1 个值
  • 可用机型:ESP32 机型 · 软 PLC 模拟器 / 上位机

math.type ​

  • 作用:区分整数/浮点数/非数字
  • 调用形态:math.type(...)(库级函数)
  • 参数:1 个参数:第 1 个为任意(必填)
  • 返回:1 个值
  • 可用机型:ESP32 机型 · 软 PLC 模拟器 / 上位机

math.ult ​

  • 作用:按无符号数比较 a 是否小于 b
  • 调用形态:math.ult(integer, integer)(库级函数)
  • 参数:2 个参数:第 1 个为整数(必填)、第 2 个为整数(必填)
  • 返回:1 个值
  • 可用机型:ESP32 机型 · 软 PLC 模拟器 / 上位机

LPPLC 工业物联网云平台 · 软硬件与云平台全栈自研