Erlang NIF 编号 return 类型
Erlang NIF number return types
我正在试验 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层的"size"数不对有关?还是 enif_(get|make)_long
不是处理这种大小的数字的正确方法?或者仅仅是 NIF 无法处理这么大的数字?
18446744073709551614
是 2^64 - 2
,因此不能放入 long long
,这很可能是范围为 -(2^63)
到 [=15= 的 64 位有符号整数].此外,enif_get_long
需要 long int
,而不是 long long
。您还应该从 enif_get_long
得到一个错误值 return,因为根据您没有检查的 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_*
的 return 值,以确保您没有处理未初始化的数据。
我正在试验 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层的"size"数不对有关?还是 enif_(get|make)_long
不是处理这种大小的数字的正确方法?或者仅仅是 NIF 无法处理这么大的数字?
18446744073709551614
是 2^64 - 2
,因此不能放入 long long
,这很可能是范围为 -(2^63)
到 [=15= 的 64 位有符号整数].此外,enif_get_long
需要 long int
,而不是 long long
。您还应该从 enif_get_long
得到一个错误值 return,因为根据您没有检查的 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_*
的 return 值,以确保您没有处理未初始化的数据。