luat_lib_bit64.c 9.1 KB

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