luat_lib_bit64.c 10 KB

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