bit64 - 32位系统上对64位数据的基本算术运算和逻辑运算
一、概述
目前合宙主推产品的LuatOS固件都有32位和64位两类;
本核心库bit64描述的是:32位系统固件上对64位数据的基本算术运算和逻辑运算;
如果你的项目一定要使用32位内核固件,并且用到了64位数据操作,可以阅读参考本核心库描述的内容;
如果你的项目使用64位内核固件,则可以按照正常的思路,对64位数据运算即可,不用阅读参考本核心库描述的内容;
32位内核固件和64位内核固件的唯一区别是是否支持64位数据的直接运算,其余功能完全相同,根据自己的项目需求来决定选择何种内核固件;
32 位数据:可以表示的数值范围较小(4 字节),对于整数数据类型,范围是 (-2^{31}) 到 (2^{31}-1)(有符号整数)或 (0) 到 (2^{32}-1)也就是(无符号整数)。
64 位数据:有更大的表示范围(8 字节),整数类型可以表示 (-2^{63}) 到 (2^{63}-1)(有符号整数)或 (0) 到 (2^{64}-1)(无符号整数)。
总结对比
数据类型 | 最小值 | 最大值 |
---|---|---|
32 位无符号整数 | 0 | 4294967295 |
32 位有符号整数 | -2147483648 | 2147483647 |
64 位无符号整数 | 0 | 18446744073709551615 |
64 位有符号整数 | -9223372036854775808 | 9223372036854775807 |
处理更大的数据位宽通常会增加功耗,因为需要更大的数据总线和更复杂的运算电路。对于一些低功耗的嵌入式系统,选择 32 位数据会有助于降低功耗。
9字节数据:本文的64bit数据为:小端格式的9字节数据的字符串,最后一个字节是类型(0是整数,1是浮点), 前面8个字节是数据。
下面来说明将十进制数字 123456
用 64 位小端字节序 数据怎么表示?
要将十进制数字 123456
表示为 64 位小端字节序 数据,需遵循小端序 “低位字节在前,高位字节在后” 的存储规则。以下是具体步骤和结果:
核心原理
- 64 位带符号整数:
123456
是正数,补码形式为符号位(0)+ 63 位数值位(高位补 0) - 小端字节序:数值的低位字节存储在内存低地址,高位字节存储在高地址(与人类读写习惯相反)
转换步骤
- 十进制转十六进制:
123456
对应的十六进制为0x000000000001E240
(共 16 位,8 字节)。按字节拆分(每 2 位十六进制为 1 字节):00 00 00 00 00 01 E2 40
(从高位到低位排列) - 按小端序反转字节顺序:小端序要求 “低位字节在前”,因此反转上述字节顺序:
40 E2 01 00 00 00 00 00
最终表示形式
表示方式 | 结果(字符串形式) |
---|---|
十六进制字符串 | "40E2010000000000" |
二进制表示(64 位) | 01000000 11100010 00000001 00000000 00000000 00000000 00000000 00000000 |
字节序列(8 字节) | 0x40, 0xE2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 |
示例
local data = 123456
local b64 = bit64.to64(data) --32bit数据转成64bit数据
log.info("hex",b64:toHex()) --打印出数据为40E201000000000000
二、核心示例
1、核心示例是指:使用本库文件提供的核心API,开发的基础业务逻辑的演示代码;
2、核心示例的作用是:帮助开发者快速理解如何使用本库,所以核心示例的逻辑都比较简单;
3、更加完整和详细的demo,请参考 LuatOS仓库 中各个产品目录下的demo/bit64
local data,b64,b32,a,b
if bit64 then
log.style(1)
log.info("bit64 演示")
data = 12345678
b64 = bit64.to64(data)
b32 = bit64.to32(b64)
log.info("i32", b32, mcu.x32(b32))
data = -12345678
b64 = bit64.to64(data)
b32 = bit64.to32(b64)
log.info("i32", b32, mcu.x32(b32))
data = 12.34234
b64 = bit64.to64(data)
b32 = bit64.to32(b64)
log.info("f32", data, b32)
data = -12.34234
b64 = bit64.to64(data)
b32 = bit64.to32(b64)
log.info("f32", data, b32)
a = bit64.to64(87654321)
b = bit64.to64(12345678)
log.info("87654321+12345678=", bit64.show(bit64.plus(a,b)))
log.info("87654321-12345678=", bit64.show(bit64.minus(a,b)))
log.info("87654321*12345678=", bit64.show(bit64.multi(a,b)))
log.info("87654321/12345678=", bit64.show(bit64.pide(a,b)))
a = bit64.to64(87654321)
b = 1234567
log.info("87654321+1234567=", bit64.show(bit64.plus(a,b)))
log.info("87654321-1234567=", bit64.show(bit64.minus(a,b)))
log.info("87654321*1234567=", bit64.show(bit64.multi(a,b)))
log.info("87654321/1234567=", bit64.show(bit64.pide(a,b)))
a = bit64.to64(87654.326)
b = bit64.to64(12345)
log.info("87654.326+12345=", 87654.326 + 12345)
log.info("87654.326+12345=", bit64.show(bit64.plus(a,b)))
log.info("87654.326-12345=", bit64.show(bit64.minus(a,b)))
log.info("87654.326*12345=", bit64.show(bit64.multi(a,b)))
log.info("87654.326/12345=", bit64.show(bit64.pide(a,b)))
a = bit64.to64(87654.32)
b = bit64.to64(12345.67)
log.info("float", "87654.32+12345.67=", 87654.32 + 12345.67)
log.info("double","87654.32+12345.67=", bit64.show(bit64.plus(a,b)))
log.info("double to float","87654.32+12345.67=", bit64.to32(bit64.plus(a,b)))
log.info("87654.32-12345.67=", bit64.show(bit64.minus(a,b)))
log.info("87654.32*12345.67=", bit64.show(bit64.multi(a,b)))
log.info("87654.32/12345.67=", bit64.show(bit64.pide(a,b)))
log.info("double to int64", "87654.32/12345.67=", bit64.show(bit64.pide(a,b,nil,true)))
a = bit64.to64(0xc0000000)
b = 2
a = bit64.shift(a,8,true)
log.info("0xc0000000 << 8 =", bit64.show(a, 16))
log.info("0xc000000000+2=", bit64.show(bit64.plus(a,b), 16))
log.info("0xc000000000-2=", bit64.show(bit64.minus(a,b), 16))
log.info("0xc000000000*2=", bit64.show(bit64.multi(a,b), 16))
log.info("0xc000000000/2=", bit64.show(bit64.pide(a,b), 16))
log.style(0)
if bit64.strtoll then
local data = bit64.strtoll("864040064024194", 10)
log.info("data", data:toHex())
log.info("data", bit64.show(data))
end
end
local function sys_run_time()
local tick64, per = mcu.tick64(true)
local per_cnt = per * 1000000
while true do
tick64, per = mcu.tick64(true)
log.info("work time","当前时间", bit64.to32(bit64.pide(tick64,per_cnt)))
sys.wait(1000)
end
end
if mcu.tick64 then
sys.taskInit(sys_run_time)
end
-- 用户代码已结束---------------------------------------------
-- 结尾总是这一句
sys.run()
-- sys.run()之后后面不要加任何语句!!!!!
三、常量详解
核心库常量,顾名思义是由合宙LuatOS内核固件中定义的、不可重新赋值或修改的固定值,在脚本代码中不需要声明,可直接调用;
bit64核心库没有常量。
四、函数详解
bit64.to32(data64bit)
功能
64bit的string类型的数据转成32bit的number类型的数据
参数
data64bit
参数含义:传入64bit数据
数据类型:string;
取值范围:9字节数据;
是否必选:必须传入此参数;
注意事项:暂无;
参数示例:{
local date = "40E201000000000000"--对应HEX字符
bit64.to32(date:fromHex())--需将HEX字符串转成Lua字符串填入
}
返回值
local b32 = bit64.to32(data64bit)
b32
含义说明:32bit数据
数据类型:number;
取值范围:无特别限制;
注意事项:暂无;
返回示例:12345678;
示例
local date = "40E201000000000000"
local b32 = bit64.to32(date:fromHex())
log.info("i32", b32) --123456
bit64.to64(data32bit)
功能
32bit的number类型的数据转成64bit的string类型的数据
参数
data32bit
参数含义:32bit数据
数据类型:number;
取值范围:无特别限制;
是否必选:必须传入此参数;
注意事项:暂无;
参数示例:123456;
返回值
local b64 = bit64.to64(data32bit)
b64
含义说明:64bit数据
数据类型:string;
取值范围:9字节数据;
注意事项:暂无;
返回示例:例如123456转为bit64后,返回值为9个字节的string类型,第1个字节的ascii值为0x40,后续8个字节的ascii值依次为:0xE2,0x01,0x00,0x00,0x00,0x00,0x00,0x00;
示例
local data = 123456
local b64 = bit64.to64(data )
log.info("b64", b64:toHex()) --40E201000000000000 18
bit64.show(a,type,flag)
功能
64bit数据格式化打印成字符串,用于显示值
参数
a
参数含义:需要打印的64bit数据
数据类型:string;
取值范围:9字节数据;
是否必选:必须传入此参数;
注意事项:暂无;
参数示例:bit64.to64(12345678);
type
参数含义:进制,10=10进制,16=16进制,默认10,只支持10或者16
数据类型:int;
取值范围:10,16;
是否必选:必须传入此参数;
注意事项:暂无;
参数示例:10;
flag
参数含义:整形是否按照无符号方式打印,true是,false不是,默认false,浮点忽略
数据类型:boolean;
取值范围:true/false;
是否必选:必须传入此参数;
注意事项:暂无;
参数示例:false;
返回值
local showdate = bit64.show(a,type,flag)
showdate
含义说明:可以打印的值
数据类型:string;
取值范围:无特别限制;
注意事项:暂无;
返回示例:12345678;
示例
local data = 12345678
local b64 = bit64.to64(data)
local showdate = bit64.show(b64)
log.info("showdate", showdate)--12345678
bit64.plus(a,b,flag1,flag2)
功能
64bit数据加,a+b,a和b中有一个为浮点,则按照浮点运算
参数
a
参数含义:加数
数据类型:string;
取值范围:9字节数据;
是否必选:必须传入此参数;
注意事项:暂无;
参数示例:bit64.to64(87654321);
参数
b
参数含义:加数
数据类型:string/number;
取值范围:无特别限制;
是否必选:必须传入此参数;
注意事项:暂无;
参数示例:bit64.to64(12345678)/1234567;
参数
flag1
参数含义:整形运算时是否按照无符号方式,true是,false不是,默认false,浮点运算忽略
数据类型:boolean;
取值范围:true/false;
是否必选:可选传入此参数,不填时,默认false,浮点运算忽略;
注意事项:暂无;
参数示例:false;
参数
flag2
参数含义:浮点运算结果是否要强制转成整数,true是,false不是,默认false,整形运算忽略
数据类型:boolean;
取值范围:true/false;
是否必选:可选传入此参数,不填时,默认false,整形运算忽略
数据类型:boolean;;
注意事项:暂无;
参数示例:true;
返回值
local c = bit64.plus(a,b,flag1,flag2)
c
含义说明:2数相加和
数据类型:string;
取值范围:9字节数据;
注意事项:暂无;
返回示例:通过bit64.show(c)格式化打印成字符串,用于显示值;
示例
local a = bit64.to64(87654321)
local b = 1234567
local c = bit64.plus(a,b)
log.info("c", bit64.show(c))--88888888
bit64.minus(a,b,flag1,flag2)
功能
64bit数据减,a-b,a和b中有一个为浮点,则按照浮点运算
参数
a
参数含义:被减数
数据类型:string;
取值范围:9字节数据;
是否必选:必须传入此参数;
注意事项:暂无;
参数示例:bit64.to64(87654321);
b
参数含义:减数
数据类型:string/number;
取值范围:无特别限制;
是否必选:必须传入此参数;
注意事项:暂无;
参数示例:bit64.to64(12345678)/1234567;
flag1
参数含义:整形运算时是否按照无符号方式,true是,false不是,默认false,浮点运算忽略
数据类型:boolean;
取值范围:true/false;
是否必选:可选传入此参数,不填时,默认false,浮点运算忽略;
注意事项:暂无;
参数示例:false;
flag2
参数含义:浮点运算结果是否要强制转成整数,true是,false不是,默认false,整形运算忽略
数据类型:boolean;
取值范围:true/false;
是否必选:可选传入此参数,不填时,默认false,整形运算忽略
数据类型:boolean;;
注意事项:暂无;
参数示例:false;
返回值
local c = bit64.minus(a,b,flag1,flag2)
c
含义说明:2数相加差
数据类型:string;
取值范围:9字节数据;
注意事项:暂无;
返回示例:通过bit64.show(c)格式化打印成字符串,用于显示值;
示例
local a = bit64.to64(87654321)
local b = 1234567
local c = bit64.minus(a,b)
log.info("c", bit64.show(c))--86419754
bit64.multi(a,b,flag1,flag2)
功能
64bit数据乘,a*b,a和b中有一个为浮点,则按照浮点运算
a
参数含义:乘数
数据类型:string;
取值范围:9字节数据;
是否必选:必须传入此参数;
注意事项:暂无;
参数示例:bit64.to64(87654.326);
b
参数含义:乘数
数据类型:string/number;
取值范围:无特别限制;
是否必选:必须传入此参数;
注意事项:暂无;
参数示例:12345678;
flag1
参数含义:整形运算时是否按照无符号方式,true是,false不是,默认false,浮点运算忽略
数据类型:boolean;
取值范围:true/false;
是否必选:可选传入此参数,不填时,默认false,浮点运算忽略;;
注意事项:暂无;
参数示例:false;
flag2
参数含义:浮点运算结果是否要强制转成整数,true是,false不是,默认false,整形运算忽略
数据类型:boolean;
取值范围:true/false;
是否必选:可选传入此参数,不填时,默认false,整形运算忽略;
注意事项:暂无;
参数示例:false;
返回值
local c = bit64.multi(a,b,flag1,flag2)
c
含义说明:2数积
数据类型:string;
取值范围:9字节数据;
注意事项:暂无;
返回示例:通过bit64.show(c)格式化打印成字符串,用于显示值;
示例
local a = bit64.to64(87654321)
local b = 1234567
local c = bit64.multi(a,b)
log.info("c", bit64.show(c))--108215132114007
bit64.pide(a,b,flag1,flag2)
功能
64bit数据除,a/b,a和b中有一个为浮点,则按照浮点运算
a
参数含义:被除数
数据类型:string;
取值范围:9字节数据;
是否必选:必须传入此参数;
注意事项:暂无;
参数示例:bit64.to64(87654321);
b
参数含义:除数
数据类型:string/number;
取值范围:无特别限制;
是否必选:必须传入此参数;
注意事项:暂无;
参数示例:bit64.to64(12345678)/1234567;
flag1
参数含义:整形运算时是否按照无符号方式,true是,false不是,默认false,浮点运算忽略
数据类型:boolean;
取值范围:true/false;
是否必选:可选传入此参数,不填时,默认false,浮点运算忽略;
注意事项:暂无;
参数示例:false;
flag2
参数含义:浮点运算结果是否要强制转成整数,true是,false不是,默认false,整形运算忽略
数据类型:boolean;
取值范围:true/false;
是否必选:可选传入此参数,不填时,默认false,整形运算忽略;
注意事项:暂无;
参数示例:false;
返回值
local c = bit64.pide(a,b,flag1,flag2)
c
含义说明:2数相除结果
数据类型:string;
取值范围:9字节数据;
注意事项:暂无;
返回示例:通过bit64.show(c)格式化打印成字符串,用于显示值;
示例
local a = bit64.to64(87654321)
local b = 1234567
local c = bit64.pide(a,b)
log.info("c", bit64.show(c))--71
bit64.shift(a,b,flag)
功能
64bit数据位移 a>>b 或者 a<<b
a
参数含义:需要位移64bit数据
数据类型:string;
取值范围:9字节数据;
是否必选:必须传入此参数;
注意事项:暂无;
参数示例:bit64.to64(0xc0000000);
b
参数含义:移动位数
数据类型:int
取值范围:1-8;
是否必选:必须传入此参数;
注意事项:暂无;
参数示例:2;
flag
参数含义:位移方向,true左移<<,false右移>>,默认false
数据类型:boolean;
取值范围:true/false;
是否必选:可选传入此参数,不填时,默认false;
注意事项:暂无;
参数示例:false;
返回值
local c = bit64.shift(a,b,flag)
c
含义说明:移后数据
数据类型:string;
取值范围:9字节数据;
注意事项:暂无;
返回示例:通过bit64.show(a, 16)格式化打印成字符串,用于显示值;
示例
local a = bit64.to64(0xc0000000)
local c = bit64.shift(a,8,true)
log.info("c", bit64.show(c, 16))--0xc000000000
bit64.strtoll(data, base)
功能
将字符串转为LongLong数据
参数
data
参数含义:待转换的数据
数据类型:string;
取值范围:>1;
是否必选:必须传入此参数;
注意事项:暂无;
参数示例:bit64.strtoll("864040064024194", 10);
base
参数含义:转换进制, 默认10, 可选16或8
数据类型:int;
取值范围:10,16,8;
是否必选:可选传入此参数,不填时,默认10;
注意事项:暂无;
参数示例:10;
返回值
local data = bit64.strtoll(data, base)
data
含义说明:转化后的数据
数据类型:string;
取值范围:9字节数据;
注意事项:暂无;
返回示例:通过bit64.show(data)格式化打印成字符串,用于显示值;
示例
-- 本API于 2023.10.27 添加
-- 提醒, 如果转换失败, 是返回9个字节的0x00
local data = bit64.strtoll("864040064024194", 10)
log.info("data", data:toHex())--827E1601D711030000 18
log.info("data", bit64.show(data))--864040064024194
五、产品支持说明
支持LuatOS开发的所有产品都支持bit64核心库。