Lua 问题

int64乘法问题

1
2
3
4
local a = int64.new(1000)
local b = 0.01
print(a + b) -- 1000
print(a * b) -- 0

原因:

  • int64乘法会触发元方法__mul
1
2
3
4
5
6
7
8
9
10
11
lua_pushstring(L, "__mul"),
lua_pushcfunction(L, _int64mul);
lua_rawset(L, -3); // 指向栈顶

static int _int64mul(lua_State* L)
{
int64_t lhs = toluas_checkint64(L, 1);
int64_t rhs = toluas_checkint64(L, 2);
toluas_pushint64(L, lhs * rhs);
return 1;
}
  • 触发元方法后调用 toluas_checkint64 检查栈中的数值类型并做类型转换,当 int64 类型和 number 类型相乘时,会将其转换成整型——(int64_t)0.01,所以相乘的结果是0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
static int64_t toluas_checkint64(lua_State* L, int pos)
{
int64_t n = 0;
int type = lua_type(L, pos);

switch(type)
{
case LUA_TNUMBER:
n = (int64_t)lua_tonumber(L, pos);
break;
case LUA_TSTRING:
n = _long(L, pos);
break;
case LUA_TUSERDATA:
if (_isint64(L, pos))
{
n = *(int64_t*)lua_touserdata(L, pos);
}
break;
default:
return luaL_typerror(L, pos, "long");
}

return n;
}

正确做法:

1
2
3
4
local a = int64.new(1000)
local b = 0.01
print(a:toDouble() + b) -- 1000.01
print(a:toDouble() * b) -- 10
1
2
3
4
5
6
7
8
9
10
11
12
static int _int64todouble(lua_State* L)
{
if (!toluas_isint64(L, 1))
{
return luaL_typerror(L, 1, "long");
}

int64_t n = toluas_toint64(L, 1);
lua_pushnumber(L, (double)n);

return 1;
}

Lua 问题
https://silhouettesforyou.github.io/2024/06/19/92509e685a8f/
Author
Xiaoming
Posted on
June 19, 2024
Licensed under