2016-05-06 6 views
1

Ich experimentiere mit NIFs und bin verwirrt darüber, mit welchen Nummerntypen Erlang arbeitet, weil ich mit meinen Genauigkeiten ein bisschen komisch bin.Erlang NIF-Zahl Rückgabetypen

Hier ist ein Beispiel:

erlang:band(18446744073709551614, 5) == 4 

Und aus dem Inneren eines NIF, die etwa wie folgt aussieht:

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); 

ich ein 1 als Ergebnis.

Hat das etwas damit zu tun, dass die C-Schicht nicht die richtige "Größe" der Nummer hat? Oder ist das enif_(get|make)_long nicht der richtige Weg, um mit einer Nummer dieser Größe umzugehen? Oder können NIFs nicht mit so großen Zahlen arbeiten?

Antwort

4

184467440737095516142^64 - 2 ist und daher nicht in den long long passen kann, die die meisten wahrscheinlich eine 64-Bit-Ganzzahl mit Vorzeichen mit dem Bereich zu -(2^63)(2^63)-1. Außerdem erfordert enif_get_long eine long int, nicht long long. Sie sollten auch einen Fehlerwert erhalten von enif_get_long wegen des Überlaufs nach der docs, die Sie nicht überprüfen.

Um an Nummern bis zu 2^64 - 1 (die die betreffende Nummer enthält) zu arbeiten, können Sie enif_get_uint64 verwenden.

Dieser Code soll (ungetestet) arbeiten:

ErlNifUInt64 l, r; 
enif_get_uint64(env, argv[0], &l); 
enif_get_uint64(env, argv[1], &r); 
return enif_make_uint64(env, l & r); 

Sie auch den Rückgabewert von enif_get_* überprüfen sollen, um sicherzustellen, dass Sie nicht auf nicht initialisierten Daten arbeiten.

+0

Dieses Beispiel funktioniert, danke für beides und die Erklärung. Ich habe nicht bemerkt, dass 'ErlNifUInt64' für diesen Fall existiert. Ich werde definitiv die Überprüfung hinzufügen, ich habe gerade mit dem Versuch gespielt, das funktioniert zu bekommen :). Wird 'ErlNifUInt64' grundsätzlich irgendeine Zahl abdecken, die Erlang erlaubt? – whitfin

+0

Nein, nur "0" bis "18446744073709551615" (der Bereich von vorzeichenlosen 64-Bit-Ganzzahlen). – Dogbert

+0

Also wäre ein geeigneter Weg, sowohl Negative als auch Positive zu behandeln, einfach das Zeichen auf der Erlang-Seite zu überprüfen und separat im NIF zu implementieren? – whitfin