1

我正在尝试使用 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 不能处理这么大的数字?

4

1 回答 1

4

184467440737095516142^64 - 2,因此不能适合 a long long,它很可能是一个 64 位有符号整数,范围-(2^63)(2^63)-1。此外,enif_get_long需要一个long int,而不是long 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);

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

于 2016-05-06T16:26:57.280 回答