Browse Source

add factorial, u64

221V 1 week ago
parent
commit
fcdf3fbc9b
3 changed files with 54 additions and 6 deletions
  1. 13 1
      README.md
  2. 14 5
      niftest.erl
  3. 27 0
      niftest.zig

+ 13 - 1
README.md

@@ -17,7 +17,19 @@ Eshell V13.2  (abort with ^G)
 {ok,niftest}
 {ok,niftest}
 2> niftest:hello().
 2> niftest:hello().
 "Hello world!"
 "Hello world!"
-3>q().
+3> niftest:factorial(5).
+120
+4> niftest:factorial(20).
+2432902008176640000
+5> niftest:factorial(21).
+** exception error: bad argument
+     in function  niftest:factorial/1
+        called as niftest:factorial(21)
+6> niftest:factorial(-5).
+** exception error: bad argument
+     in function  niftest:factorial/1
+        called as niftest:factorial(-5)
+7>q().
 
 
 
 
 
 

+ 14 - 5
niftest.erl

@@ -1,11 +1,16 @@
 -module(niftest).
 -module(niftest).
+-on_load(init/0).
 
 
--export([init/0, hello/0]).
-
-
--nifs([hello/0]).
+-export([
+  init/0,
+  hello/0,
+  factorial/1
+]).
 
 
--on_load(init/0).
+-nifs([
+  hello/0,
+  factorial/1
+]).
 
 
 
 
 init() ->
 init() ->
@@ -15,3 +20,7 @@ init() ->
 hello() ->
 hello() ->
   erlang:nif_error("NIF library not loaded").
   erlang:nif_error("NIF library not loaded").
 
 
+
+factorial(N) when is_integer(N), N >= 0 ->
+  "NIF not loaded".
+

+ 27 - 0
niftest.zig

@@ -13,6 +13,27 @@ pub export fn hello(env: ?*erl.ErlNifEnv, argc: c_int, argv: [*c]const erl.ERL_N
 }
 }
 
 
 
 
+pub export fn factorial(env: ?*erl.ErlNifEnv, argc: c_int, argv: [*c]const erl.ERL_NIF_TERM) erl.ERL_NIF_TERM{
+  if(argc != 1){
+    return erl.enif_make_badarg(env);
+  }
+  
+  var n: c_long = undefined;
+  if(erl.enif_get_long(env, argv[0], &n) == 0 or n < 0 or n > 20){
+    return erl.enif_make_badarg(env);
+  }
+  
+  var result: c_ulonglong = 1;
+  var i: c_ulonglong = @as(c_ulonglong, @intCast(n) );
+  //var i = n;
+  while(i > 1) : (i -= 1){
+    result *= i;
+  }
+  
+  return erl.enif_make_uint64(env, result);
+}
+
+
 const nif_funcs = [_]erl.ErlNifFunc{
 const nif_funcs = [_]erl.ErlNifFunc{
   .{
   .{
     .name = "hello",
     .name = "hello",
@@ -20,6 +41,12 @@ const nif_funcs = [_]erl.ErlNifFunc{
     .fptr = hello,
     .fptr = hello,
     .flags = 0,
     .flags = 0,
   },
   },
+  .{
+    .name = "factorial",
+    .arity = 1,
+    .fptr = factorial,
+    .flags = 0,
+  },
 };
 };