Sproto 默认不支持浮点数, 但我们项目在一个模块用到了,而且调用频率还挺高,作为一个懒人,我不想扩展Sproto库:
- 可能引入bug
- 更新skynet新版本的时候也麻烦
因为使用频率挺高,使用转为字符串再转回来性能损失挺大,想想直接转为int比较好, 这个方案的前提是客户端和服务端都采用相同的浮点数标准,如IEEE754和字节序。
代码如下:
union float_number {
double d;
int64_t i;
}
static bool check_support() {
assert(sizeof(int64_t) == sizeof(double)); /*double must be 64bit*/
assert(0x3ff0000000000000 == ((union float_number){1.0}).i); /*check little-endian and IEEE 754*/
return true;
}
static int lua_encode_float(lua_State* L) {
assert(check_support());
union float_number number;
number.d = lua_tonumber(L, 1);
lua_pushinteger(L, number.i);
return 1;
}
static int lua_decode_float(lua_State* L) {
assert(check_support());
union float_number number;
number.i = lua_tointeger(L, 1);
lua_pushnumber(L, number.d);
return 1;
}
C#的BitConverter提供了这个的功能:
public static double TransferToFloat(this long value)
{
return BitConverter.Int64BitsToDouble(value);
}
public static long TransferToInt64(this double value)
{
return BitConverter.DoubleToInt64Bits(value);
}