2016-05-06 14 views
1

私はNIFを試していますが、Erlangがどのような数値型を扱っているのか混乱しています。ここでErlang NIF番号の戻り値の型

は例です:

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

184467440737095516142^64 - 2であり、したがって、最も可能性の高い(2^63)-1範囲-(2^63)と64ビットの符号付き整数である、long longに収まりません。また、enif_get_longは、であり、ではありません。チェックしていないdocsに従ってオーバーフローするため、エラー値がenif_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_*の戻り値をチェックする必要があります。

+0

この例はうまくいきます、それとその説明の両方に感謝します。私は、このケースでは 'ErlNifUInt64'が存在することを認識しませんでした。私は間違いなくチェックを追加します、私はちょうどこれを取得しようとして遊んでいた:)。 'ErlNifUInt64'は基本的にErlangが許可する任意の数をカバーしますか? – whitfin

+0

いいえ、 '0 '〜' 18446744073709551615'(符号なし64ビット整数の範囲)。 – Dogbert

+0

したがって、ポジティブだけでなくネガも扱う適切な方法は、Erlang側のサインをチェックし、NIFに個別に実装することでしょうか? – whitfin