| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512 |
- /*
- @module bit64
- @summary 32位系统上对64位数据的基本算术运算和逻辑运算
- @version 0.1
- @date 2023.03.11
- @tag LUAT_USE_BIT64
- @demo bit64
- @note 64位数据用9字节string存储,byte7~byte0存数据,byte8=0表示整形,其他表示浮点
- */
- #include "luat_base.h"
- #include "luat_mem.h"
- #define LUAT_LOG_TAG "bit64"
- #include "luat_log.h"
- #include <stdlib.h>
- #define D64_FLAG 0x01
- #ifdef LUAT_USE_BIT64
- /**
- 64bit数据转成32bit输出
- @api bit64.to32(data64bit)
- @string 9字节数据
- @return any 根据64bit数据输出int或者number
- */
- static int l_bit64_to32(lua_State *L)
- {
- double d64;
- int64_t i64;
- size_t len;
- const char *data = luaL_checklstring(L, 1, &len);
- if (len != 9)
- {
- lua_pushnil(L);
- }
- if (data[8])
- {
- memcpy(&d64, data, 8);
- lua_pushnumber(L, (lua_Number)d64);
- }
- else
- {
- memcpy(&i64, data, 8);
- lua_pushinteger(L, (lua_Integer)i64);
- }
- return 1;
- }
- /**
- 32bit数据转成64bit数据
- @api bit64.to64(data32bit)
- @int/number 32bit数据
- @return string 9字节数据
- */
- static int l_bit64_to64(lua_State *L)
- {
- double d64;
- uint64_t u64;
- uint8_t data[9] = {0};
- if (lua_isinteger(L, 1))
- {
- u64 = (lua_Unsigned)lua_tointeger(L, 1);
- memcpy(data, &u64, 8);
- }
- else if (lua_isnumber(L, 1))
- {
- d64 = lua_tonumber(L, 1);
- data[8] = D64_FLAG;
- memcpy(data, &d64, 8);
- }
- lua_pushlstring(L, (const char*)data, 9);
- return 1;
- }
- /**
- 64bit数据格式化打印成字符串,用于显示值
- @api bit64.show(a,type,flag)
- @string 需要打印的64bit数据
- @int 进制,10=10进制,16=16进制,默认10,只支持10或者16
- @boolean 整形是否按照无符号方式打印,true是,false不是,默认false,浮点忽略
- @return string 可以打印的值
- */
- static int l_bit64_show(lua_State *L)
- {
- int64_t i64 = 0;
- double d64 = 0;
- size_t len = 0;
- uint8_t data[64] = {0};
- uint8_t flag = 0;
- const char *string = luaL_checklstring(L, 1, &len);
- if (len != 9)
- {
- lua_pushnil(L);
- return 1;
- }
- if (string[8])
- {
- memcpy(&d64, string, 8);
- }
- else
- {
- memcpy(&i64, string, 8);
- }
- uint8_t type = luaL_optinteger(L, 2, 10);
- if (lua_isboolean(L, 3))
- {
- flag = lua_toboolean(L, 3);
- }
- if (type != 16)
- {
- if (string[8])
- {
- len = snprintf_((char*)data, 63, "%f", d64);
- }
- else
- {
- if (flag)
- {
- len = snprintf_((char*)data, 63, "%llu", i64);
- }
- else
- {
- len = snprintf_((char*)data, 63, "%lld", (uint64_t)i64);
- }
- }
- }
- else
- {
- if (string[8])
- {
- len = snprintf_((char*)data, 63, "0x%llx", d64);
- }
- else
- {
- len = snprintf_((char*)data, 63, "0x%llx", i64);
- }
- }
- lua_pushlstring(L, (const char*)data, len);
- return 1;
- }
- static int l_bit64_calculate(lua_State *L, uint8_t op)
- {
- double d64_a = 0,d64_b = 0;
- int64_t i64_a = 0, i64_b = 0;
- uint64_t u64 = 0;
- size_t len = 0;
- uint8_t data[9] = {0};
- uint8_t flag1 = 0;
- uint8_t flag2 = 0;
- uint8_t fa= 0,fb =0;
- const char *string = luaL_checklstring(L, 1, &len);
- if (len != 9)
- {
- goto DONE;
- }
- fa = string[8];
- if (fa)
- {
- memcpy(&d64_a, string, 8);
- }
- else
- {
- memcpy(&i64_a, string, 8);
- }
- if (lua_isinteger(L, 2))
- {
- i64_b = lua_tointeger(L, 2);
- fb = 0;
- }
- else if (lua_isnumber(L, 2))
- {
- d64_b = lua_tonumber(L, 2);
- fb = 1;
- }
- else
- {
- string = luaL_checklstring(L, 2, &len);
- if (len != 9)
- {
- goto DONE;
- }
- fb = string[8];
- if (fb)
- {
- memcpy(&d64_b, string, 8);
- }
- else
- {
- memcpy(&i64_b, string, 8);
- }
- }
- if (lua_isboolean(L, 3))
- {
- flag1 = lua_toboolean(L, 3);
- }
- if (lua_isboolean(L, 4))
- {
- flag2 = lua_toboolean(L, 4);
- }
- switch(op)
- {
- case 0:
- if (fa && fb)
- {
- d64_a = d64_a + d64_b;
- goto FLOAT_OP;
- }
- if (fa && !fb)
- {
- d64_a = d64_a + i64_b;
- goto FLOAT_OP;
- }
- if (!fa && fb)
- {
- d64_a = i64_a + d64_b;
- goto FLOAT_OP;
- }
- if (!fa && !fb)
- {
- if (flag1)
- {
- u64 = (uint64_t)i64_a + (uint64_t)i64_b;
- memcpy(data, &u64, 8);
- }
- else
- {
- i64_a = i64_a + i64_b;
- memcpy(data, &i64_a, 8);
- }
- goto DONE;
- }
- break;
- case 1:
- if (fa && fb)
- {
- d64_a = d64_a - d64_b;
- goto FLOAT_OP;
- }
- if (fa && !fb)
- {
- d64_a = d64_a - i64_b;
- goto FLOAT_OP;
- }
- if (!fa && fb)
- {
- d64_a = i64_a - d64_b;
- goto FLOAT_OP;
- }
- if (!fa && !fb)
- {
- if (flag1)
- {
- u64 = (uint64_t)i64_a - (uint64_t)i64_b;
- memcpy(data, &u64, 8);
- }
- else
- {
- i64_a = i64_a - i64_b;
- memcpy(data, &i64_a, 8);
- }
- goto DONE;
- }
- break;
- case 2:
- if (fa && fb)
- {
- d64_a = d64_a * d64_b;
- goto FLOAT_OP;
- }
- if (fa && !fb)
- {
- d64_a = d64_a * i64_b;
- goto FLOAT_OP;
- }
- if (!fa && fb)
- {
- d64_a = i64_a * d64_b;
- goto FLOAT_OP;
- }
- if (!fa && !fb)
- {
- if (flag1)
- {
- u64 = (uint64_t)i64_a * (uint64_t)i64_b;
- memcpy(data, &u64, 8);
- }
- else
- {
- i64_a = i64_a * i64_b;
- memcpy(data, &i64_a, 8);
- }
- goto DONE;
- }
- break;
- case 3:
- if (fa && fb)
- {
- d64_a = d64_a / d64_b;
- goto FLOAT_OP;
- }
- if (fa && !fb)
- {
- d64_a = d64_a / i64_b;
- goto FLOAT_OP;
- }
- if (!fa && fb)
- {
- d64_a = i64_a / d64_b;
- goto FLOAT_OP;
- }
- if (!fa && !fb)
- {
- if (flag1)
- {
- u64 = (uint64_t)i64_a / (uint64_t)i64_b;
- memcpy(data, &u64, 8);
- }
- else
- {
- i64_a = i64_a / i64_b;
- memcpy(data, &i64_a, 8);
- }
- goto DONE;
- }
- break;
- }
- FLOAT_OP:
- if (flag2)
- {
- i64_a = d64_a;
- memcpy(data, &i64_a, 8);
- }
- else
- {
- data[8] = D64_FLAG;
- memcpy(data, &d64_a, 8);
- }
- goto DONE;
- DONE:
- lua_pushlstring(L, (const char*)data, 9);
- return 1;
- }
- /**
- 64bit数据加,a+b,a和b中有一个为浮点,则按照浮点运算
- @api bit64.plus(a,b,flag1,flag2)
- @string a
- @string/int/number b
- @boolean 整形运算时是否按照无符号方式,true是,false不是,默认false,浮点运算忽略
- @boolean 浮点运算结果是否要强制转成整数,true是,false不是,默认false,整形运算忽略
- @return string 9字节数据
- */
- static int l_bit64_plus(lua_State *L)
- {
- return l_bit64_calculate(L, 0);
- }
- /**
- 64bit数据减,a-b,a和b中有一个为浮点,则按照浮点运算
- @api bit64.minus(a,b,flag1,flag2)
- @string a
- @string/int/number b
- @boolean 整形运算时是否按照无符号方式,true是,false不是,默认false,浮点运算忽略
- @boolean 浮点运算结果是否要强制转成整数,true是,false不是,默认false,整形运算忽略
- @return string 9字节数据
- */
- static int l_bit64_minus(lua_State *L)
- {
- return l_bit64_calculate(L, 1);
- }
- /**
- 64bit数据乘,a*b,a和b中有一个为浮点,则按照浮点运算
- @api bit64.multi(a,b,flag1,flag2)
- @string a
- @string/int/number b
- @boolean 整形运算时是否按照无符号方式,true是,false不是,默认false,浮点运算忽略
- @boolean 浮点运算结果是否要强制转成整数,true是,false不是,默认false,整形运算忽略
- @return string 9字节数据
- */
- static int l_bit64_multiply(lua_State *L)
- {
- return l_bit64_calculate(L, 2);
- }
- /**
- 64bit数据除,a/b,a和b中有一个为浮点,则按照浮点运算
- @api bit64.pide(a,b,flag1,flag2)
- @string a
- @string/int/number b
- @boolean 整形运算时是否按照无符号方式,true是,false不是,默认false,浮点运算忽略
- @boolean 浮点运算结果是否要强制转成整数,true是,false不是,默认false,整形运算忽略
- @return string 9字节数据
- */
- static int l_bit64_pide(lua_State *L)
- {
- return l_bit64_calculate(L, 3);
- }
- /**
- 64bit数据位移 a>>b 或者 a<<b
- @api bit64.shift(a,b,flag)
- @string a
- @int b
- @boolean 位移方向,true左移<<,false右移>>,默认false
- @return string 9字节数据
- */
- static int l_bit64_shift(lua_State *L)
- {
- uint64_t u64;
- uint32_t pos = 0;
- size_t len;
- uint8_t data[9] = {0};
- uint8_t flag = 0;
- const char *string = luaL_checklstring(L, 1, &len);
- if (len != 9)
- {
- goto DONE;
- }
- data[8] = string[8];
- memcpy(&u64, string, 8);
- if (lua_isinteger(L, 2))
- {
- pos = lua_tointeger(L, 2);
- if (!pos)
- {
- goto DONE;
- }
- }
- else
- {
- goto DONE;
- }
- if (lua_isboolean(L, 3))
- {
- flag = lua_toboolean(L, 3);
- }
- if (flag)
- {
- u64 = u64 << pos;
- }
- else
- {
- u64 = u64 >> pos;
- }
- data[8] = string[8];
- memcpy(data, &u64, 8);
- lua_pushlstring(L, (const char*)data, 9);
- return 1;
- DONE:
- lua_pushlstring(L, (const char*)string, len);
- return 1;
- }
- /*
- 将字符串转为LongLong数据
- @api bit64.strtoll(data, base)
- @string 待转换的数据,必须存在
- @int 转换进制, 默认10, 可选16或8
- @return string 9字节数据
- @usage
- -- 本API于 2023.10.27 添加
- -- 提醒, 如果转换失败, 是返回9个字节的0x00
- local data = bit64.strtoll("864040064024194", 10)
- log.info("data", data:toHex())
- log.info("data", bit64.show(data))
- */
- static int l_bit64_strtoll(lua_State *L) {
- size_t len = 0;
- int64_t value = 0;
- int base = 0;
- char* stopstring;
- uint8_t re[9] = {0};
- const char* data = luaL_checklstring(L, 1, &len);
- base = luaL_optinteger(L, 2, 10);
- if (len == 0) {
- return 0;
- }
- value = strtoll(data, &stopstring, base);
- re[8] = 0;
- memcpy(re, (const char*)&value, 8);
- lua_pushlstring(L, (const char*)re, 9);
- return 1;
- }
- #include "rotable2.h"
- static const rotable_Reg_t reg_bit64[] = {
- {"to32", ROREG_FUNC(l_bit64_to32)},
- {"to64", ROREG_FUNC(l_bit64_to64)},
- {"plus", ROREG_FUNC(l_bit64_plus)},
- {"minus", ROREG_FUNC(l_bit64_minus)},
- {"multi", ROREG_FUNC(l_bit64_multiply)},
- {"pide", ROREG_FUNC(l_bit64_pide)},
- {"shift", ROREG_FUNC(l_bit64_shift)},
- {"show", ROREG_FUNC(l_bit64_show)},
- {"strtoll", ROREG_FUNC(l_bit64_strtoll)},
- {NULL, ROREG_INT(0)}
- };
- LUAMOD_API int luaopen_bit64(lua_State *L)
- {
- luat_newlib2(L, reg_bit64);
- return 1;
- }
- #endif
|