|
@@ -13,24 +13,59 @@ pub export fn hello(env: ?*erl.ErlNifEnv, argc: c_int, argv: [*c]const erl.ERL_N
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
+fn u128_to_buf(value: u128, buffer: *align(1) [40]u8) usize{
|
|
|
|
+ if(value == 0){
|
|
|
|
+ buffer[0] = '0';
|
|
|
|
+ return 1;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ var i: usize = 0;
|
|
|
|
+ var n = value;
|
|
|
|
+ while(n > 0){
|
|
|
|
+ buffer[i] = @as(u8, @intCast('0' + (n % 10)) );
|
|
|
|
+ n /= 10;
|
|
|
|
+ i += 1;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ var j: usize = 0;
|
|
|
|
+ while(j < i / 2) : (j += 1){
|
|
|
|
+ const temp = buffer[j];
|
|
|
|
+ buffer[j] = buffer[i - 1 - j];
|
|
|
|
+ buffer[i - 1 - j] = temp;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return i;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
pub export fn factorial(env: ?*erl.ErlNifEnv, argc: c_int, argv: [*c]const erl.ERL_NIF_TERM) erl.ERL_NIF_TERM{
|
|
pub export fn factorial(env: ?*erl.ErlNifEnv, argc: c_int, argv: [*c]const erl.ERL_NIF_TERM) erl.ERL_NIF_TERM{
|
|
if(argc != 1){
|
|
if(argc != 1){
|
|
return erl.enif_make_badarg(env);
|
|
return erl.enif_make_badarg(env);
|
|
}
|
|
}
|
|
|
|
|
|
var n: c_long = undefined;
|
|
var n: c_long = undefined;
|
|
- if(erl.enif_get_long(env, argv[0], &n) == 0 or n < 0 or n > 20){
|
|
|
|
|
|
+ if(erl.enif_get_long(env, argv[0], &n) == 0 or n < 0){
|
|
return erl.enif_make_badarg(env);
|
|
return erl.enif_make_badarg(env);
|
|
}
|
|
}
|
|
|
|
|
|
- var result: c_ulonglong = 1;
|
|
|
|
- var i: c_ulonglong = @as(c_ulonglong, @intCast(n) );
|
|
|
|
|
|
+ if(n > 34){ // max n for max factorial for u128
|
|
|
|
+ return erl.enif_make_tuple2(env,
|
|
|
|
+ erl.enif_make_atom(env, "error"),
|
|
|
|
+ erl.enif_make_string(env, "input too large, max is 34", 1)
|
|
|
|
+ );
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ var result: u128 = 1;
|
|
|
|
+ var i = @as(u128, @intCast(n) );
|
|
//var i = n;
|
|
//var i = n;
|
|
while(i > 1) : (i -= 1){
|
|
while(i > 1) : (i -= 1){
|
|
result *= i;
|
|
result *= i;
|
|
}
|
|
}
|
|
|
|
|
|
- return erl.enif_make_uint64(env, result);
|
|
|
|
|
|
+ var buf: [40]u8 = undefined;
|
|
|
|
+ const len = u128_to_buf(result, &buf);
|
|
|
|
+
|
|
|
|
+ return erl.enif_make_string_len(env, buf[0..len].ptr, len, 1); // , ERL_NIF_LATIN1);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|