找回密码
 register

QQ登录

只需一步,快速开始

搜索
查看: 4|回复: 0

[每天自学] 天龙八部源端 x64:Lua4 增加 bit32 库(位运算)用法教程

[复制链接]
  • 打卡等级:本地老炮
  • 打卡总天数:385
  • 打卡月天数:2
  • 打卡总奖励:383
  • 最近打卡:2026-01-02 01:39:27
Waylee 发表于 2026-1-2 01:39 | 显示全部楼层 |阅读模式 | Google Chrome | Windows 10

马上注册,查看网站隐藏内容!!

您需要 登录 才可以下载或查看,没有账号?register

×

源端 Lua4 本身没位运算,我这边补了一个 bit32(Lua5.2 那套名字),脚本里直接用 bit32.xxx()

注意:Lua4 不支持 0x1234 这种十六进制字面量,写数字请用十进制。


1)新增函数一览(新增函数 / 作用)

新增函数 作用
bit32.band(...) 按位与(支持多个参数)
bit32.bor(...) 按位或(支持多个参数)
bit32.bxor(...) 按位异或(支持多个参数)
bit32.bnot(x) 按位取反(32 位)
bit32.btest(...) band(...) 结果是否非 0(返回布尔)
bit32.lshift(x, n) 左移 n 位(32 位截断)
bit32.rshift(x, n) 逻辑右移 n 位(高位补 0)
bit32.arshift(x, n) 算术右移 n 位(按符号扩展)
bit32.lrotate(x, n) 循环左移(rotate left)
bit32.rrotate(x, n) 循环右移(rotate right)
bit32.extract(x, field [, width]) 取位段:从 field 开始取 width 位
bit32.replace(x, v, field [, width]) 替换位段:把 x 的某段替换成 v

说明:全部运算按 32 位无符号处理,超出会自动截断到 0 ~ 2^32-1。


2)基础示例:AND/OR/XOR/NOT

-- 1) band:按位与
print(bit32.band(7, 3))          -- 7(111) & 3(011) = 3

-- 2) bor:按位或
print(bit32.bor(5, 2))           -- 5(101) | 2(010) = 7

-- 3) bxor:按位异或
print(bit32.bxor(6, 3))          -- 6(110) ^ 3(011) = 5

-- 4) bnot:按位取反(32位)
print(bit32.bnot(0))             -- 4294967295

3)btest:检测某些位是否存在(最常用)

local flags = 5   -- 二进制 0101

-- 判断第 0 位是否为 1(mask=1)
print(bit32.btest(flags, 1))     -- true

-- 判断第 1 位是否为 1(mask=2)
print(bit32.btest(flags, 2))     -- false

-- 判断第 2 位是否为 1(mask=4)
print(bit32.btest(flags, 4))     -- true

4)shift:左移 / 逻辑右移 / 算术右移

-- 左移:1 << 3 = 8
print(bit32.lshift(1, 3))        -- 8

-- 逻辑右移:8 >> 2 = 2
print(bit32.rshift(8, 2))        -- 2

-- 算术右移:主要用在“带符号意义”的右移
-- 例如把 0x80000000 当成负数的符号扩展(Lua4里别写0x,用十进制2147483648)
print(bit32.arshift(2147483648, 1))  -- 3221225472 (看起来像负数右移的效果)

rshift 永远补 0;arshift 会按最高位做符号扩展。


5)rotate:循环移位(转圈)

-- rrotate:把最低位转到最高位
print(bit32.rrotate(1, 1))       -- 2147483648

-- lrotate:把最高位转到最低位
print(bit32.lrotate(2147483648, 1))  -- 1

0x00000001 在 Lua4 里会语法错,直接写 1


6)extract:取某段 bit(字段)

extract(x, field, width)

  • field:从第几位开始(0 起)
  • width:取多少位(默认 1)
-- 例:x = 13 (二进制 1101)
local x = 13

-- 取第0位(最低位),宽度1 -> 1
print(bit32.extract(x, 0, 1))    -- 1

-- 取第1位,宽度2(取bits[1..2])
print(bit32.extract(x, 1, 2))    -- 2  (1101 的 [01]?? 结果按位段算)

(实际用它最多是从标志位里抠某个字段值。)


7)replace:替换某段 bit(字段写入)

replace(x, v, field, width)
xfield 开始的 width 位替换为 v(只取 v 的低 width 位)

-- x=0,把第4位开始的3位写成 5(二进制101)
local x = 0
local y = bit32.replace(x, 5, 4, 3)
print(y)   -- 5 << 4 = 80

8)Lua4 写法注意点(别踩坑)

  1. Lua4 不支持 0x...

    • 0x80000000 请写十进制 2147483648
  2. 参数必须是整数意义的 number

    • 传 1.2 这种会报 “number has no integer representation”
  3. 所有结果都会截断到 32 位

    • 超过 0xFFFFFFFF 会自动 mod 2^32

9)测试代码

print("=== band/bor/bxor/bnot (single + multi args) ===")
print(bit32.band(7, 3))                 -- 3
print(bit32.band(255, 240, 15))         -- 0
print(bit32.bor(5, 2))                  -- 7
print(bit32.bor(1, 2, 4, 8))            -- 15
print(bit32.bxor(6, 3))                 -- 5
print(bit32.bxor(1, 2, 4))              -- 7
print(bit32.bnot(0))                    -- 4294967295
print(bit32.bnot(4294967295))           -- 0

print("\n=== btest ===")
print(bit32.btest(5, 1))                -- true(通常打印 1)
print(bit32.btest(5, 2))                -- false(通常打印 nil)
print(bit32.btest(0, 1))                -- false(通常打印 nil)

print("\n=== shifts ===")
print(bit32.lshift(1, 3))               -- 8
print(bit32.lshift(1, 31))              -- 2147483648
print(bit32.lshift(1, 40))              -- 0 (>=32 位直接 0)
print(bit32.rshift(8, 2))               -- 2
print(bit32.rshift(2147483648, 31))     -- 1
print(bit32.rshift(1, 1))               -- 0
print(bit32.arshift(2147483648, 1))     -- 3221225472 (0xC0000000)
print(bit32.arshift(4294967295, 1))     -- 4294967295 (0xFFFFFFFF)

print("\n=== rotates ===")
print(bit32.lrotate(1, 1))              -- 2
print(bit32.lrotate(2147483648, 1))     -- 1
print(bit32.rrotate(1, 1))              -- 2147483648
print(bit32.rrotate(2, 1))              -- 1
print(bit32.rrotate(1, 0))              -- 1

print("\n=== extract/replace ===")
print(bit32.extract(240, 4, 4))         -- 15  (240 = 0xF0)
print(bit32.extract(240, 0, 4))         -- 0
print(bit32.extract(15, 0, 4))          -- 15
print(bit32.replace(0, 15, 4, 4))       -- 240
print(bit32.replace(255, 0, 4, 4))      -- 15  (255=0xFF -> 清掉高4位)
print(bit32.replace(240, 3, 0, 2))      -- 243 (0xF0 -> 0xF3)

输出结果:

=== band/bor/bxor/bnot (single + multi args) ===
3
0
7
15
5
7
4294967295
0

=== btest ===
1
nil
nil

=== shifts ===
8
2147483648
0
2
1
0
3221225472
4294967295

=== rotates ===
2
1
2147483648
1
1

=== extract/replace ===
15
0
15
240
15
243
您需要登录后才可以回帖 登录 | register

本版积分规则

雪舞知识库 ( 浙ICP备15015590号-1 | 萌ICP备20232229号|浙公网安备33048102000118号 ) |网站地图|天天打卡

GMT+8, 2026-1-2 05:02 , Processed in 0.087549 second(s), 6 queries , Redis On.

Powered by Discuz! X3.5 Licensed

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表