Erlang NIF 数字返回类型

whi*_*fin 2 c erlang erlang-nif

我正在尝试 NIF,但我对 Erlang 正在使用的数字类型感到困惑,因为我的精度有些奇怪。

这是一个例子:

erlang:band(18446744073709551614, 5) == 4
Run Code Online (Sandbox Code Playgroud)

从 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);
Run Code Online (Sandbox Code Playgroud)

我得到一个1结果。

这是否与 C 层未保存正确的数字“大小”有关?或者这enif_(get|make)_long不是处理如此大小的数字的正确方法?或者仅仅是 NIF 无法处理这么大的数字?

Dog*_*ert 5

184467440737095516142^64 - 2,因此不能放入 a 中,它很可能是一个范围为long long的 64 位有符号整数。另外,需要一个,而不是。根据您未检查的文档,您还应该收到由于溢出而返回的错误值。-(2^63)(2^63)-1enif_get_longlong intlong longenif_get_long

要处理最多的数字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);
Run Code Online (Sandbox Code Playgroud)

您还应该检查返回值enif_get_*以确保您没有处理未初始化的数据。