我正在尝试使用NIF,我对Erlang正在使用的数字类型感到困惑,因为我的精确度让我感到有点古怪。
以下是一个例子:
erlang:band(18446744073709551614, 5) == 4
从NIF里面看起来像这样:
long long l, r;
enif_get_long(env, argv[0], &l);
enif_get_long(env, argv[1], &r);
return enif_make_long(env, l & r);
结果我得到1
。
这与C层没有保持数字的正确“大小”有关吗?或者enif_(get|make)_long
是不是处理这么大的正确方法?或者仅仅是NIF无法使用这么大的数字?
答案 0 :(得分:4)
18446744073709551614
为2^64 - 2
,因此无法放入long long
,这很可能是范围为-(2^63)
到(2^63)-1
的64位有符号整数。另外,enif_get_long
需要long int
,而不是long long
。您还应该收到enif_get_long
返回的错误值,因为根据您未检查的docs发生溢出。
要处理最高2^64 - 1
的数字(包括相关数字),您可以使用enif_get_uint64
。
此代码应该有效(未经测试):
ErlNifUInt64 l, r;
enif_get_uint64(env, argv[0], &l);
enif_get_uint64(env, argv[1], &r);
return enif_make_uint64(env, l & r);
您还应该检查enif_get_*
的返回值,以确保您没有处理未初始化的数据。