Lua int64 的支持
虽然今天发了 twitter ,以及向 lua mailling list 里投递了消息,不过想想还是写一篇 blog 记录一下。
Lua 只支持一种 number ,默认是 double 类型。虽然你可以通过修改 luaconf.h 里的定义,把 lua number 改成 int64 。但是为了 int64 类型而放弃浮点数,恐怕不是大多数人想要的。
int64 通常用在 uuid 上,也就是说不需要对其数学运算,只需要可以比较就好了。我以前最喜欢的做法是用 8 bytes 长的 string 来表示一个 int64 。这样,即可以做唯一的 key 用,又不用做复杂的扩展。
在 pbc 的 lua binding 库 中,对 fixed64 类型,我就是这样处理的。
今天遇到新的需求,有同学希望可以在项目中直接处理 64bit 的 timestamp 。这就需要对 int64 做数学运算了。
虽然最终我们去掉了这个需求(使用 32bit 的 timestamp ),但我还是忍不住去想,到底怎样在 lua 中支持 64bit 整数运算最好。
在 luajit 中,是定义了一个 userdata 并重载其运算符完成的。即,你可以用 ffi.cast(\"int64_t\",0) 来构造一个 64bit 的 0 。
姑且不谈 userdata 的额外开销问题,这样做有一个问题就是当 64bit 的 cdata 做 table 的 key 的时候,相同值的 int64 并不是同一个 key 。
我觉得有一个更轻量的方式来解决 int64 支持的问题。那就是在 64 位平台上,我们完全可以用 lightuserdata 无损失的表示一个 int64 。
通过给 lightuserdata 设置 metatable ,我们可以接管它的数据运算。唯一不足的是,比较一个 int64 和普通的 lua number 是否相等时,lua 不能隐式的做转换。(而大于小于比较则没有问题)
我花了半小时实现了我的想法,放在了 github 上 ,有兴趣的同学可以拿去用。
这个库只提供了一个显式的 api ,即构造一个 int64 数字。可以从 lua number 构造,也支持从一个 8 字节宽的小头的字符串来构造。实际在内存储存的是一个 lightuserdata 即一个 64bit 指针(所以这个库不适用于 32 位平台)。你也可以通过 C 接口 lua_pushlightuserdata 来把一个 64bit 整数压入堆栈。
把 int64 转换为普通的 lua number 借用了 # 操作符。
希望这个小东西对你有帮助。
建议继续学习:
- Nginx与Lua (阅读:4671)
- Lua GC 的源码剖析 (2) (阅读:3889)
- Ameba , 一个简单的 lua 多线程实现 (阅读:3567)
- Lua GC 的源码剖析 (4) (阅读:3419)
- 使用 luajit 的 ffi 绑定 zeromq (阅读:3343)
- Proto Buffers in Lua (阅读:3131)
- Lua GC 的源码剖析 (1) (阅读:3057)
- 一个 Lua 内存泄露检查工具 (阅读:3015)
- Lua GC 的源码剖析 (6) 完结 (阅读:2597)
- Lua GC 的源码剖析 (3) (阅读:2325)
扫一扫订阅我的微信号:IT技术博客大学习
- 作者:云风的 BLOG 来源: 云风的 BLOG
- 标签: int64 Lua
- 发布时间:2012-04-12 13:26:48
- [68] Go Reflect 性能
- [68] 如何拿下简短的域名
- [67] Oracle MTS模式下 进程地址与会话信
- [62] IOS安全–浅谈关于IOS加固的几种方法
- [61] 图书馆的世界纪录
- [60] 【社会化设计】自我(self)部分――欢迎区
- [58] android 开发入门
- [56] 视觉调整-设计师 vs. 逻辑
- [49] 给自己的字体课(一)——英文字体基础
- [48] 读书笔记-壹百度:百度十年千倍的29条法则