C Erlang NIF数返回类型

C Erlang NIF数返回类型,c,erlang,erlang-nif,C,Erlang,Erlang Nif,我正在尝试NIFs,我对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); 结果我得到一

我正在尝试NIFs,我对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层没有保持正确的数字“大小”有关?或者说,处理这种规模的数字不是正确的方法吗?或者仅仅是NIFs不能处理这么大的数字?

18446744073709551614
2^64-2
,因此不能放入
long
,它很可能是一个64位有符号整数,范围为
-(2^63)
(2^63)-1
。另外,
enif_get_long
需要
long int
,而不是
long
。您还应该从
enif_get_long
返回一个错误值,因为您没有检查的溢出

要处理高达
2^64-1
(其中包括有问题的数字)的数字,可以使用

此代码应该有效(未经测试):


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

18446744073709551614
2^64-2
,因此不能放入
long
,这很可能是一个范围为
-(2^63)
(2^63)的64位有符号整数-1
。另外,
enif_get_long
需要
long int
,而不是
long
。您还应该从
enif_get_long
返回一个错误值,因为您没有检查的溢出

要处理高达
2^64-1
(其中包括有问题的数字)的数字,可以使用

此代码应该有效(未经测试):


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

该示例确实有效,谢谢您的解释。我没有意识到这个案例中存在
ErlNifUInt64
。我肯定会添加检查,我只是在玩弄如何让它工作:)。
ErlNifUInt64
将基本覆盖Erlang允许的任何数字吗?不,仅
0
18446744073709551615
(无符号64位整数的范围)。那么,处理否定和肯定的适当方法是检查Erlang端的符号并分别在NIF中实现吗?您希望支持的数字范围是什么?理想情况下,您可以从Erlang中使用任何东西(我正在考虑将某些东西移植到NIF以加快速度,但希望保持Erlang版本的行为)该示例确实有效,感谢您的支持和解释。我没有意识到本例中存在
ErlNifUInt64
。我肯定会添加检查,我只是在尝试让它工作:)。
ErlNifUInt64
将基本覆盖Erlang允许的任何数字吗?不,仅
0
18446744073709551615
(无符号64位整数的范围)。那么,处理否定和肯定的适当方法是检查Erlang端的符号并分别在NIF中实现吗?您希望支持的数字范围是什么?理想情况下,您可以从Erlang中使用任何东西(我正在考虑将一些东西移植到NIF以加快速度,但希望保持Erlang版本的性能)
ErlNifUInt64 l, r;
enif_get_uint64(env, argv[0], &l);
enif_get_uint64(env, argv[1], &r);
return enif_make_uint64(env, l & r);