diff options
-rw-r--r-- | ChangeLog | 10 | ||||
-rw-r--r-- | arith.c | 53 | ||||
-rw-r--r-- | eval.c | 2 | ||||
-rw-r--r-- | lib.h | 2 | ||||
-rw-r--r-- | txr.1 | 4 |
5 files changed, 71 insertions, 0 deletions
@@ -1,5 +1,15 @@ 2011-12-13 Kaz Kylheku <kaz@kylheku.com> + * arith.c (exptmod, gcd): New functions. + + * eval.c (eval_init): New functions registered as intrisics. + + * lib.h (exptmod, gcd): Declared. + + * txr.1: Documentation stubs added. + +2011-12-13 Kaz Kylheku <kaz@kylheku.com> + * arith.c (evenp, oddp): New functions. * eval.c (eval_init): New functions registered as intrinsics. @@ -932,6 +932,34 @@ val expt(val anum, val bnum) abort(); } +val exptmod(val base, val exp, val mod) +{ + val n; + + if (!numberp(base) || !numberp(exp) || !numberp(mod)) + goto inval; + + if (fixnump(base)) + base = bignum(c_num(base)); + + if (fixnump(exp)) + exp = bignum(c_num(exp)); + + if (fixnump(mod)) + mod = bignum(c_num(mod)); + + n = make_bignum(); + + if (mp_exptmod(mp(base), mp(exp), mp(mod), mp(n)) != MP_OKAY) + goto inval; + + return n; +inval: + uw_throwf(error_s, lit("exptmod: invalid operands ~s ~s ~s"), + base, exp, mod, nao); + abort(); +} + static int_ptr_t isqrt_fixnum(int_ptr_t a) { int_ptr_t mask = (int_ptr_t) 1 << (highest_bit(a) / 2); @@ -962,6 +990,31 @@ val isqrt(val anum) uw_throwf(error_s, lit("sqrt: invalid operand ~s"), anum, nao); } +val gcd(val anum, val bnum) +{ + val n; + + if (!numberp(anum) || !numberp(bnum)) + goto inval; + + if (fixnump(anum)) + anum = bignum(c_num(anum)); + + if (fixnump(bnum)) + bnum = bignum(c_num(bnum)); + + n = make_bignum(); + + if (mp_gcd(mp(anum), mp(bnum), mp(n)) != MP_OKAY) + goto inval; + + return n; +inval: + uw_throwf(error_s, lit("gcd: invalid operands ~s ~s ~s"), + anum, bnum, nao); + abort(); +} + void arith_init(void) { mp_init(&NUM_MAX_MP); @@ -1160,7 +1160,9 @@ void eval_init(void) reg_fun(intern(lit("trunc"), user_package), func_n2(trunc)); reg_fun(intern(lit("mod"), user_package), func_n2(mod)); reg_fun(intern(lit("expt"), user_package), func_n0v(exptv)); + reg_fun(intern(lit("exptmod"), user_package), func_n3(exptmod)); reg_fun(intern(lit("sqrt"), user_package), func_n1(isqrt)); + reg_fun(intern(lit("gcd"), user_package), func_n2(gcd)); reg_fun(intern(lit("fixnump"), user_package), func_n1(fixnump)); reg_fun(intern(lit("bignump"), user_package), func_n1(bignump)); reg_fun(intern(lit("numberp"), user_package), func_n1(numberp)); @@ -391,7 +391,9 @@ val maxv(val first, val rest); val minv(val first, val rest); val expt(val base, val exp); val exptv(val nlist); +val exptmod(val base, val exp, val mod); val isqrt(val anum); +val gcd(val anum, val bnum); val string_own(wchar_t *str); val string(const wchar_t *str); val string_utf8(const char *str); @@ -4811,6 +4811,10 @@ The following are Lisp functions and variables built-in to TXR. .SS Arithmetic functions +, -, *, trunc, mod, expt, sqrt +.SS Arithmetic function exptmod + +.SS Arithmetic function gcd + .SS Arithmetic function abs .SS Functions fixnump, bignump, numberp |