最近把一个 native 游戏移植到 HTML5,客户端和服务端都是 C++ ,而且游戏金币经常性超过 2^31
,所以服务端的大爷们很任性地使用了 int64 。
这下问题来了,Javascript 不支持 int64 。
说服服务端的大爷们改用 32bit 是不可能的。说服大爷们使用字符串也是不可能的。说服策划重新设置数值使其小于 2^31
也是不可能的。
有句话怎么说的?如果不能反抗,那就默默享受吧……
看我这个 Javascript 前端菜鸟如何应对!
本着不重复(tou)造轮(lan)子的优良传统,我发现了这样几个已有的实现方案:
lizi 这位比我还懒的程序员同学实现的 方法 ,这酸爽……
package lz.jprotoc { import flash.utils.IDataInput; /** * ... * @author lizhi http://matrix3d.github.io/ */ public class Int64 { public var low:uint = 0; public var high:uint = 0; public function Int64(low:uint=0,high:uint=0) { this.low = low; this.high = high; } public function equal(v:Int64):Boolean { if (v == null) return false; return (v.low == low) && (v.high == high); } public function isZero():Boolean { return low == 0 && high == 0; } public function toString():String { return "high:0x" + high.toString(16)+" low:0x" + low.toString(16); } } }
虽然是 AS3 写的,但转成 JS 也是分分钟。
dom 同学用 ByteArray 来保存每个字节 (同样是 AS3),然后将其转成字符串来显示,缺点和上面 lizi 的一样,就是无法计算。
node-int64 采用 Javascript 的 Number 来实现对超过 int32 的数值的保存。由于 Number 采用 双精度浮点数 来保存数值,因此该值的范围只能在 +/- 2^^53
的范围内。
这是我最终的选择。因为金币的值在客户端是会参与计算的,但估计在游戏的有生之年都不可能大于 2^53
。
(全文完)