diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2017-08-05 16:54:41 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2017-08-05 16:54:41 -0700 |
commit | 905a08374e2901e97b18e58d970f95a25ec6fc10 (patch) | |
tree | 5ec8498b29b05908c3d46da92d9f387cc7037350 /arith.c | |
parent | d6ba8dd31733e6f3b455a8f746087b33066fef81 (diff) | |
download | txr-905a08374e2901e97b18e58d970f95a25ec6fc10.tar.gz txr-905a08374e2901e97b18e58d970f95a25ec6fc10.tar.bz2 txr-905a08374e2901e97b18e58d970f95a25ec6fc10.zip |
New functions digpow and digits.
* arith.c (digcommon): New static function.
(digpow, digits): New functions.
(arith_init): New digpow and digits intrinsic functions
registered.
* arith.h (digpow, digits): Declared.
* txr.1: New functions documented.
Diffstat (limited to 'arith.c')
-rw-r--r-- | arith.c | 50 |
1 files changed, 50 insertions, 0 deletions
@@ -2848,6 +2848,54 @@ val bits(val obj) return normalize(bignum_from_uintptr(coerce(uint_ptr_t, obj))); } +static val digcommon(int pow, val self, val n, val base_in) +{ + val r = default_arg_strict(base_in, num_fast(10)); + + if (!integerp(n) || minusp(n)) + uw_throwf(error_s, lit("~a: value ~s must be positive integer"), + self, n, nao); + if (!integerp(r) || lt(r, one)) + uw_throwf(error_s, lit("~a: base ~s must be positive integer"), + self, r, nao); + + { + val k = r; + val p = nil, p0; + list_collect_decl (out, ptail); + + while (lt(k, n)) { + push(k, &p); + k = mul(k, r); + } + + while ((p0 = pop(&p))) { + cnum i = 0; + while (ge(n, p0)) { + i++; + n = minus(n, p0); + } + ptail = list_collect(ptail, if3(pow, + mul(num_fast(i), p0), + num_fast(i))); + } + + list_collect(ptail, n); + + return out; + } +} + +val digpow(val n, val base) +{ + return digcommon(1, lit("digpow"), n, base); +} + +val digits(val n, val base) +{ + return digcommon(0, lit("digits"), n, base); +} + void arith_init(void) { mp_init(&NUM_MAX_MP); @@ -2882,6 +2930,8 @@ void arith_init(void) reg_varl(intern(lit("%e%"), user_package), flo(M_E)); reg_fun(intern(lit("bits"), system_package), func_n1(bits)); + reg_fun(intern(lit("digpow"), user_package), func_n2o(digpow, 1)); + reg_fun(intern(lit("digits"), user_package), func_n2o(digits, 1)); } void arith_free_all(void) |