位运算(bit)
一、位运算概述
位运算是一种在计算机系统中对二进制数位进行操作的运算.由于计算机内部数据的存储和处理都是以二进制形式进行的,位运算能够直接对整数的二进制位进行高效操作.位运算包括与(&)、或(|)、异或(^)、非(~)、左移(<<)和右移(>>)等基本操作。
二、演示功能概述
本文通过了解位操作的 API 函数,并用代码演示功能来熟悉 Air780E-LuatOS-软件 demo-基础服务-位运算(bit)。
三、准备硬件环境
“古人云:‘工欲善其事,必先利其器。’在深入介绍本功能示例之前,我们首先需要确保以下硬件环境的准备工作已经完成。”
参考:硬件环境清单 - luatos@air8101 - 合宙文档中心,准备以及组装好硬件环境。
四、软件环境
“凡事预则立,不预则废。”在详细阐述本功能示例之前,我们需先精心筹备好以下软件环境。
1. Luatools 工具;
2. 内核固件文件(底层 core 固件文件):LuatOS-SoC_V10001_Air8101.soc;参考项目使用的内核固件;
3. luatos 需要的脚本和资源文件
脚本和资源文件:https://gitee.com/openLuat/LuatOS-Air8101/tree/master/demo/bit
lib 脚本文件:使用 Luatools 烧录时,勾选 添加默认 lib 选项,使用默认 lib 脚本文件;
准备好软件环境之后,接下来查看如何烧录项目文件到 Air8101 开发板 - luatos@air8101 - 合宙文档中心,将本篇文章中演示使用的项目文件烧录到 Air8101 开发板中。
五、API 说明
位操作支持库
5.1 bit.bnot( value )
取反,等价于 C 语言中的~
参数
**参数** | **类型** | **释义** | **取值** |
value | number | 需要取反的值 | 0x0000 0000~0xFFFF FFFF |
返回值
**返回值** | **类型** | **释义** | **取值** |
result | number | 取反之后的值 | 0x0000 0000~0xFFFF FFFF |
例子
--支持 32 位比特数按位取反
print(bit.bnot(5))
--按位取反,输出-6
5.2 bit.band( val1, val2, … valn )
与运算,等价于 C 语言中的 val1 & val2 & … & valn
参数
**参数** | **类型** | **释义** |
val1 | number | 第一个参数 |
val2 | number | 第二个参数 |
valn | number | 第 n 个参数 |
返回值
**返回值** | **类型** | **释义** |
result | number | 与运算之后的结果 |
例子
print(bit.band(1,1))
--与,输出 1
5.3 bit.bor( val1, val2, … valn )
或运算,等价于 C 里面的 val1 | val2 | … | valn
注:对于 Air780E 建议不要超过 3 个参数
参数
**参数** | **类型** | **释义** |
val1 | number | 第一个参数 |
val2 | number | 第二个参数 |
valn | number | 第 n 个参数 |
返回值
**返回值** | **类型** | **释义** |
result | number | 或运算之后的结果 |
例子
print(bit.bor(1,2))
--或,输出 3
5.4 bit.bxor( val1, val2, … valn )
异或运算,等价于 C 语言中的 val1 ^ val2 ^ … ^ valn
参数
**参数** | **类型** | **释义** |
val1 | number | 第一个参数 |
val2 | number | 第二个参数 |
valn | number | 第 n 个参数 |
返回值
**返回值** | **类型** | **释义** |
result | number | 异或运算之后的结果, 此处为位异或 |
例子
print(bit.bxor(2,3,5))
--异或结果为 4
5.5 bit.lshift( value, shift )
逻辑左移,等价于 C 语言中的 value << shift
参数
**参数** | **类型** | **释义** |
value | number | 移位的值 |
shift | number | 移位的位置 |
返回值
**返回值** | **类型** | **释义** |
result | number | 逻辑左移之后的结果 |
例子
print(bit.lshift(1,2))
--逻辑左移,“100”,输出为 4
5.6 bit.rshift( value, shift )
逻辑右移,等价于 C 语言中的 value >> shift
参数
**参数** | **类型** | **释义** |
value | number | 移位的值 |
shift | number | 移位的位置 |
返回值
**返回值** | **类型** | **释义** |
result | number | 逻辑右移之后的结果 |
例子
print(bit.rshift(4,2))
--逻辑右移,“001”,输出为 1
5.7 bit.arshift( value, shift )
算数右移
参数
**参数** | **类型** | **释义** |
value | number | 移位的值 |
shift | number | 移位的位置 |
返回值
**返回值** | **类型** | **释义** |
result | number | 逻辑右移之后的结果 |
例子
print(bit.arshift(2,2))
--算数右移,左边添加的数与符号有关,输出为 0
5.8 bit.bit( position )
左移运算,等价于 C 语言中的 1 << position
参数
**参数** | **类型** | **释义** |
position | number | 移位的位置 |
返回值
**返回值** | **类型** | **释义** |
result | number | 需要移位的位置 |
例子
print(bit.bit(2))
--参数是位数,作用是 1 向左移动两位,打印出 4
5.9 bit.isset(value, position)
测试位数是否被置 1
参数
**参数** | **类型** | **释义** |
value | number | 被测试的值 |
position | number | 被测试的位置 |
返回值
**返回值** | **类型** | **释义** | **取值** |
result | bool | true:该位被置 1,false:其他 | true/false |
例子
-- 例子 1
print(bit.isset(5,0))
--第一个参数是是测试数字,第二个是测试位置.从右向左数 0 到 7.是 1 返回 true,否则返回 false,该返回 true
-- 例子 2
print(bit.isset(5,1))
--打印 false
-- 例子 3
print(bit.isset(5,2))
--打印 true-- 例子 4_print(bit.isset(5,3))--返回返回 false
5.10 bit.isclear(value, position)
测试位数是否被置 0
参数
**参数** | **类型** | **释义** |
value | number | 被测试的值 |
position | number | 被测试的位置 |
返回值
**返回值** | **类型** | **释义** | **取值** |
result | bool | true:该位被置 0,false:其他 | true/false |
例子
print(bit.isclear(5,0))
--与上面的相反
print(bit.isclear(5,1))
print(bit.isclear(5,2))
print(bit.isclear(5,3))
5.11 bit.set(value, pos1, pos2, …posn)
置 1
参数
**参数** | **类型** | **释义** |
value | number | 基数(需要改变的值) |
pos1 | number | 第一位置 |
pos2 | number | 第二位置 |
posn | number | 第 n 位置 |
返回值
**返回值** | **类型** | **释义** |
result | bool | 置 1 之后的值 |
例子
-- 把 0 的第 0,1,2,3 位值为 1
print(bit.set(0,0,1,2,3))
--在相应的位数置 1,打印 15
5.12 bit.clear(value, pos1, pos2, …posn)
置 0
参数
**参数** | **类型** | **释义** |
value | number | 基数(需要改变的值) |
pos1 | number | 第一位置 |
pos2 | number | 第二位置 |
posn | number | 第 n 位置 |
返回值
**返回值** | **类型** | **释义** |
result | bool | 置 0 之后的值 |
例子
-- 把 5 的第 0,2 位置为 0
print(bit.clear(5,0,2))
--在相应的位置置 0,打印 0
六、功能验证
6.1 示例代码
下面根据 demo 演示位操作的功能,可以参考以下示例代码.
示例代码如下:
local function log_bit()
log.info("按位取反,输出-6",bit.bnot(5))
log.info("与,--输出1",bit.band(1,1))
log.info("或,--输出3",bit.bor(1,2))
log.info("异或结果为4",bit.bxor(2,3,5))
log.info("逻辑左移,“100”,输出为4",bit.lshift(1,2))
log.info("逻辑右移,“001”,输出为1",bit.rshift(4,2))
log.info("算数右移,左边添加的数与符号有关,输出为0",bit.arshift(2,2))
log.info("参数是位数,作用是1向左移动两位,打印出4",bit.bit(2))
log.info("测试位数是否被置1",bit.isset(5,0))--第一个参数是是测试数字,第二个是测试位置.从右向左数0到7.是1返回true,否则返回false,该返回true
log.info("测试位数是否被置1",bit.isset(5,1))--打印false
log.info("测试位数是否被置1",bit.isset(5,2))--打印true
log.info("测试位数是否被置1",bit.isset(5,3))--返回返回false
log.info("测试位数是否被置0",bit.isclear(5,0))----与上面的相反
log.info("测试位数是否被置0",bit.isclear(5,1))
log.info("测试位数是否被置0",bit.isclear(5,2))
log.info("测试位数是否被置0",bit.isclear(5,3))
log.info("把0的第0,1,2,3位值为1",bit.set(0,0,1,2,3))--在相应的位数置1,打印15
log.info("把5的第0,2位置为0",bit.clear(5,0,2))--在相应的位置置0,打印0
end
6.2 对应 log 信息
[2025-01-01 23:33:57.382] I/pm reset reason: 0
[2025-01-01 23:33:57.382] D/pm boot up by power on
[2025-01-01 23:33:57.382] D/pm poweron reason 0
[2025-01-01 23:33:57.382] D/main UID: 4C4D19333C
[2025-01-01 23:33:57.382] cal:W(8):temp in otp is:567
[2025-01-01 23:33:57.491] D/main STA MAC: C8478C8F027E
[2025-01-01 23:33:57.491] D/main AP MAC: C8478C8F027F
[2025-01-01 23:33:57.491] D/main BLE MAC: C8478C8F0280
[2025-01-01 23:33:57.491] D/main ETH MAC: C8478C8F0281
[2025-01-01 23:33:57.491] I/main LuatOS@D602 base 24.10 bsp V10001 32bit
[2025-01-01 23:33:57.507] I/main ROM Build: Jan 1 2025 20:17:40
[2025-01-01 23:33:57.507] D/main loadlibs luavm 204792 14256 14336
[2025-01-01 23:33:57.507] D/main loadlibs sys 301544 95320 95320
[2025-01-01 23:33:57.507] I/user.main bit64_test 1.0.0
[2025-01-01 23:33:57.507] I/user.按位取反,输出-6 -6
[2025-01-01 23:33:57.507] I/user.与,--输出1 1
[2025-01-01 23:33:57.507] I/user.或,--输出3 3
[2025-01-01 23:33:57.507] I/user.异或结果为4 4
[2025-01-01 23:33:57.507] I/user.逻辑左移,“100”,输出为4 4
[2025-01-01 23:33:57.507] I/user.逻辑右移,“001”,输出为1 1
[2025-01-01 23:33:57.507] I/user.算数右移,左边添加的数与符号有关,输出为0 0
[2025-01-01 23:33:57.507] I/user.参数是位数,作用是1向左移动两位,打印出4 4
[2025-01-01 23:33:57.507] I/user.测试位数是否被置1 true
[2025-01-01 23:33:57.507] I/user.测试位数是否被置1 false
[2025-01-01 23:33:57.507] I/user.测试位数是否被置1 true
[2025-01-01 23:33:57.507] I/user.测试位数是否被置1 false
[2025-01-01 23:33:57.507] I/user.测试位数是否被置0 false
[2025-01-01 23:33:57.507] I/user.测试位数是否被置0 true
[2025-01-01 23:33:57.507] I/user.测试位数是否被置0 false
[2025-01-01 23:33:57.507] I/user.测试位数是否被置0 true
[2025-01-01 23:33:57.507] I/user.把0的第0,1,2,3位值为1 15
[2025-01-01 23:33:57.507] I/user.把5的第0,2位置为0 0