luat_lib_bit64.c 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515
  1. /*
  2. @module bit64
  3. @summary 32位系统上对64位数据的基本算术运算和逻辑运算
  4. @version 0.1
  5. @date 2023.03.11
  6. @tag LUAT_USE_BIT64
  7. @demo bit64
  8. @note 64位数据用9字节string存储,byte7~byte0存数据,byte8=0表示整形,其他表示浮点
  9. @usage
  10. -- 注意, 本代码注意用于 32位系统上对64位数据(主要是Long Long数据)的基本算术运算和逻辑运算
  11. */
  12. #include "luat_base.h"
  13. #include "luat_mem.h"
  14. #define LUAT_LOG_TAG "bit64"
  15. #include "luat_log.h"
  16. #include <stdlib.h>
  17. #define D64_FLAG 0x01
  18. #ifdef LUAT_USE_BIT64
  19. /**
  20. 64bit数据转成32bit输出
  21. @api bit64.to32(data64bit)
  22. @string 9字节数据
  23. @return any 根据64bit数据输出int或者number
  24. */
  25. static int l_bit64_to32(lua_State *L)
  26. {
  27. double d64;
  28. int64_t i64;
  29. size_t len;
  30. const char *data = luaL_checklstring(L, 1, &len);
  31. if (len != 9)
  32. {
  33. lua_pushnil(L);
  34. }
  35. if (data[8])
  36. {
  37. memcpy(&d64, data, 8);
  38. lua_pushnumber(L, (lua_Number)d64);
  39. }
  40. else
  41. {
  42. memcpy(&i64, data, 8);
  43. lua_pushinteger(L, (lua_Integer)i64);
  44. }
  45. return 1;
  46. }
  47. /**
  48. 32bit数据转成64bit数据
  49. @api bit64.to64(data32bit)
  50. @int/number 32bit数据
  51. @return string 9字节数据
  52. */
  53. static int l_bit64_to64(lua_State *L)
  54. {
  55. double d64;
  56. uint64_t u64;
  57. uint8_t data[9] = {0};
  58. if (lua_isinteger(L, 1))
  59. {
  60. u64 = (lua_Unsigned)lua_tointeger(L, 1);
  61. memcpy(data, &u64, 8);
  62. }
  63. else if (lua_isnumber(L, 1))
  64. {
  65. d64 = lua_tonumber(L, 1);
  66. data[8] = D64_FLAG;
  67. memcpy(data, &d64, 8);
  68. }
  69. lua_pushlstring(L, (const char*)data, 9);
  70. return 1;
  71. }
  72. /**
  73. 64bit数据格式化打印成字符串,用于显示值
  74. @api bit64.show(a,type,flag)
  75. @string 需要打印的64bit数据
  76. @int 进制,10=10进制,16=16进制,默认10,只支持10或者16
  77. @boolean 整形是否按照无符号方式打印,true是,false不是,默认false,浮点忽略
  78. @return string 可以打印的值
  79. */
  80. static int l_bit64_show(lua_State *L)
  81. {
  82. int64_t i64 = 0;
  83. double d64 = 0;
  84. size_t len = 0;
  85. uint8_t data[64] = {0};
  86. uint8_t flag = 0;
  87. const char *string = luaL_checklstring(L, 1, &len);
  88. if (len != 9)
  89. {
  90. lua_pushnil(L);
  91. return 1;
  92. }
  93. if (string[8])
  94. {
  95. memcpy(&d64, string, 8);
  96. }
  97. else
  98. {
  99. memcpy(&i64, string, 8);
  100. }
  101. uint8_t type = luaL_optinteger(L, 2, 10);
  102. if (lua_isboolean(L, 3))
  103. {
  104. flag = lua_toboolean(L, 3);
  105. }
  106. if (type != 16)
  107. {
  108. if (string[8])
  109. {
  110. len = snprintf_((char*)data, 63, "%f", d64);
  111. }
  112. else
  113. {
  114. if (flag)
  115. {
  116. len = snprintf_((char*)data, 63, "%llu", i64);
  117. }
  118. else
  119. {
  120. len = snprintf_((char*)data, 63, "%lld", (uint64_t)i64);
  121. }
  122. }
  123. }
  124. else
  125. {
  126. if (string[8])
  127. {
  128. len = snprintf_((char*)data, 63, "0x%llx", d64);
  129. }
  130. else
  131. {
  132. len = snprintf_((char*)data, 63, "0x%llx", i64);
  133. }
  134. }
  135. lua_pushlstring(L, (const char*)data, len);
  136. return 1;
  137. }
  138. static int l_bit64_calculate(lua_State *L, uint8_t op)
  139. {
  140. double d64_a = 0,d64_b = 0;
  141. int64_t i64_a = 0, i64_b = 0;
  142. uint64_t u64 = 0;
  143. size_t len = 0;
  144. uint8_t data[9] = {0};
  145. uint8_t flag1 = 0;
  146. uint8_t flag2 = 0;
  147. uint8_t fa= 0,fb =0;
  148. const char *string = luaL_checklstring(L, 1, &len);
  149. if (len != 9)
  150. {
  151. goto DONE;
  152. }
  153. fa = string[8];
  154. if (fa)
  155. {
  156. memcpy(&d64_a, string, 8);
  157. }
  158. else
  159. {
  160. memcpy(&i64_a, string, 8);
  161. }
  162. if (lua_isinteger(L, 2))
  163. {
  164. i64_b = lua_tointeger(L, 2);
  165. fb = 0;
  166. }
  167. else if (lua_isnumber(L, 2))
  168. {
  169. d64_b = lua_tonumber(L, 2);
  170. fb = 1;
  171. }
  172. else
  173. {
  174. string = luaL_checklstring(L, 2, &len);
  175. if (len != 9)
  176. {
  177. goto DONE;
  178. }
  179. fb = string[8];
  180. if (fb)
  181. {
  182. memcpy(&d64_b, string, 8);
  183. }
  184. else
  185. {
  186. memcpy(&i64_b, string, 8);
  187. }
  188. }
  189. if (lua_isboolean(L, 3))
  190. {
  191. flag1 = lua_toboolean(L, 3);
  192. }
  193. if (lua_isboolean(L, 4))
  194. {
  195. flag2 = lua_toboolean(L, 4);
  196. }
  197. switch(op)
  198. {
  199. case 0:
  200. if (fa && fb)
  201. {
  202. d64_a = d64_a + d64_b;
  203. goto FLOAT_OP;
  204. }
  205. if (fa && !fb)
  206. {
  207. d64_a = d64_a + i64_b;
  208. goto FLOAT_OP;
  209. }
  210. if (!fa && fb)
  211. {
  212. d64_a = i64_a + d64_b;
  213. goto FLOAT_OP;
  214. }
  215. if (!fa && !fb)
  216. {
  217. if (flag1)
  218. {
  219. u64 = (uint64_t)i64_a + (uint64_t)i64_b;
  220. memcpy(data, &u64, 8);
  221. }
  222. else
  223. {
  224. i64_a = i64_a + i64_b;
  225. memcpy(data, &i64_a, 8);
  226. }
  227. goto DONE;
  228. }
  229. break;
  230. case 1:
  231. if (fa && fb)
  232. {
  233. d64_a = d64_a - d64_b;
  234. goto FLOAT_OP;
  235. }
  236. if (fa && !fb)
  237. {
  238. d64_a = d64_a - i64_b;
  239. goto FLOAT_OP;
  240. }
  241. if (!fa && fb)
  242. {
  243. d64_a = i64_a - d64_b;
  244. goto FLOAT_OP;
  245. }
  246. if (!fa && !fb)
  247. {
  248. if (flag1)
  249. {
  250. u64 = (uint64_t)i64_a - (uint64_t)i64_b;
  251. memcpy(data, &u64, 8);
  252. }
  253. else
  254. {
  255. i64_a = i64_a - i64_b;
  256. memcpy(data, &i64_a, 8);
  257. }
  258. goto DONE;
  259. }
  260. break;
  261. case 2:
  262. if (fa && fb)
  263. {
  264. d64_a = d64_a * d64_b;
  265. goto FLOAT_OP;
  266. }
  267. if (fa && !fb)
  268. {
  269. d64_a = d64_a * i64_b;
  270. goto FLOAT_OP;
  271. }
  272. if (!fa && fb)
  273. {
  274. d64_a = i64_a * d64_b;
  275. goto FLOAT_OP;
  276. }
  277. if (!fa && !fb)
  278. {
  279. if (flag1)
  280. {
  281. u64 = (uint64_t)i64_a * (uint64_t)i64_b;
  282. memcpy(data, &u64, 8);
  283. }
  284. else
  285. {
  286. i64_a = i64_a * i64_b;
  287. memcpy(data, &i64_a, 8);
  288. }
  289. goto DONE;
  290. }
  291. break;
  292. case 3:
  293. if (fa && fb)
  294. {
  295. d64_a = d64_a / d64_b;
  296. goto FLOAT_OP;
  297. }
  298. if (fa && !fb)
  299. {
  300. d64_a = d64_a / i64_b;
  301. goto FLOAT_OP;
  302. }
  303. if (!fa && fb)
  304. {
  305. d64_a = i64_a / d64_b;
  306. goto FLOAT_OP;
  307. }
  308. if (!fa && !fb)
  309. {
  310. if (flag1)
  311. {
  312. u64 = (uint64_t)i64_a / (uint64_t)i64_b;
  313. memcpy(data, &u64, 8);
  314. }
  315. else
  316. {
  317. i64_a = i64_a / i64_b;
  318. memcpy(data, &i64_a, 8);
  319. }
  320. goto DONE;
  321. }
  322. break;
  323. }
  324. FLOAT_OP:
  325. if (flag2)
  326. {
  327. i64_a = d64_a;
  328. memcpy(data, &i64_a, 8);
  329. }
  330. else
  331. {
  332. data[8] = D64_FLAG;
  333. memcpy(data, &d64_a, 8);
  334. }
  335. goto DONE;
  336. DONE:
  337. lua_pushlstring(L, (const char*)data, 9);
  338. return 1;
  339. }
  340. /**
  341. 64bit数据加,a+b,a和b中有一个为浮点,则按照浮点运算
  342. @api bit64.plus(a,b,flag1,flag2)
  343. @string a
  344. @string/int/number b
  345. @boolean 整形运算时是否按照无符号方式,true是,false不是,默认false,浮点运算忽略
  346. @boolean 浮点运算结果是否要强制转成整数,true是,false不是,默认false,整形运算忽略
  347. @return string 9字节数据
  348. */
  349. static int l_bit64_plus(lua_State *L)
  350. {
  351. return l_bit64_calculate(L, 0);
  352. }
  353. /**
  354. 64bit数据减,a-b,a和b中有一个为浮点,则按照浮点运算
  355. @api bit64.minus(a,b,flag1,flag2)
  356. @string a
  357. @string/int/number b
  358. @boolean 整形运算时是否按照无符号方式,true是,false不是,默认false,浮点运算忽略
  359. @boolean 浮点运算结果是否要强制转成整数,true是,false不是,默认false,整形运算忽略
  360. @return string 9字节数据
  361. */
  362. static int l_bit64_minus(lua_State *L)
  363. {
  364. return l_bit64_calculate(L, 1);
  365. }
  366. /**
  367. 64bit数据乘,a*b,a和b中有一个为浮点,则按照浮点运算
  368. @api bit64.multi(a,b,flag1,flag2)
  369. @string a
  370. @string/int/number b
  371. @boolean 整形运算时是否按照无符号方式,true是,false不是,默认false,浮点运算忽略
  372. @boolean 浮点运算结果是否要强制转成整数,true是,false不是,默认false,整形运算忽略
  373. @return string 9字节数据
  374. */
  375. static int l_bit64_multiply(lua_State *L)
  376. {
  377. return l_bit64_calculate(L, 2);
  378. }
  379. /**
  380. 64bit数据除,a/b,a和b中有一个为浮点,则按照浮点运算
  381. @api bit64.pide(a,b,flag1,flag2)
  382. @string a
  383. @string/int/number b
  384. @boolean 整形运算时是否按照无符号方式,true是,false不是,默认false,浮点运算忽略
  385. @boolean 浮点运算结果是否要强制转成整数,true是,false不是,默认false,整形运算忽略
  386. @return string 9字节数据
  387. */
  388. static int l_bit64_pide(lua_State *L)
  389. {
  390. return l_bit64_calculate(L, 3);
  391. }
  392. /**
  393. 64bit数据位移 a>>b 或者 a<<b
  394. @api bit64.shift(a,b,flag)
  395. @string a
  396. @int b
  397. @boolean 位移方向,true左移<<,false右移>>,默认false
  398. @return string 9字节数据
  399. */
  400. static int l_bit64_shift(lua_State *L)
  401. {
  402. uint64_t u64;
  403. uint32_t pos = 0;
  404. size_t len;
  405. uint8_t data[9] = {0};
  406. uint8_t flag = 0;
  407. const char *string = luaL_checklstring(L, 1, &len);
  408. if (len != 9)
  409. {
  410. goto DONE;
  411. }
  412. data[8] = string[8];
  413. memcpy(&u64, string, 8);
  414. if (lua_isinteger(L, 2))
  415. {
  416. pos = lua_tointeger(L, 2);
  417. if (!pos)
  418. {
  419. goto DONE;
  420. }
  421. }
  422. else
  423. {
  424. goto DONE;
  425. }
  426. if (lua_isboolean(L, 3))
  427. {
  428. flag = lua_toboolean(L, 3);
  429. }
  430. if (flag)
  431. {
  432. u64 = u64 << pos;
  433. }
  434. else
  435. {
  436. u64 = u64 >> pos;
  437. }
  438. data[8] = string[8];
  439. memcpy(data, &u64, 8);
  440. lua_pushlstring(L, (const char*)data, 9);
  441. return 1;
  442. DONE:
  443. lua_pushlstring(L, (const char*)string, len);
  444. return 1;
  445. }
  446. /*
  447. 将字符串转为LongLong数据
  448. @api bit64.strtoll(data, base)
  449. @string 待转换的数据,必须存在
  450. @int 转换进制, 默认10, 可选16或8
  451. @return string 9字节数据
  452. @usage
  453. -- 本API于 2023.10.27 添加
  454. -- 提醒, 如果转换失败, 是返回9个字节的0x00
  455. local data = bit64.strtoll("864040064024194", 10)
  456. log.info("data", data:toHex())
  457. log.info("data", bit64.show(data))
  458. */
  459. static int l_bit64_strtoll(lua_State *L) {
  460. size_t len = 0;
  461. int64_t value = 0;
  462. int base = 0;
  463. char* stopstring;
  464. uint8_t re[9] = {0};
  465. const char* data = luaL_checklstring(L, 1, &len);
  466. base = luaL_optinteger(L, 2, 10);
  467. if (len == 0) {
  468. return 0;
  469. }
  470. value = strtoll(data, &stopstring, base);
  471. re[8] = 0;
  472. memcpy(re, (const char*)&value, 8);
  473. lua_pushlstring(L, (const char*)re, 9);
  474. return 1;
  475. }
  476. #include "rotable2.h"
  477. static const rotable_Reg_t reg_bit64[] = {
  478. {"to32", ROREG_FUNC(l_bit64_to32)},
  479. {"to64", ROREG_FUNC(l_bit64_to64)},
  480. {"plus", ROREG_FUNC(l_bit64_plus)},
  481. {"minus", ROREG_FUNC(l_bit64_minus)},
  482. {"multi", ROREG_FUNC(l_bit64_multiply)},
  483. {"pide", ROREG_FUNC(l_bit64_pide)},
  484. {"shift", ROREG_FUNC(l_bit64_shift)},
  485. {"show", ROREG_FUNC(l_bit64_show)},
  486. {"strtoll", ROREG_FUNC(l_bit64_strtoll)},
  487. {NULL, ROREG_INT(0)}
  488. };
  489. LUAMOD_API int luaopen_bit64(lua_State *L)
  490. {
  491. luat_newlib2(L, reg_bit64);
  492. return 1;
  493. }
  494. #endif