diff options
author | aiju <devnull@localhost> | 2016-08-31 13:00:50 +0000 |
---|---|---|
committer | aiju <devnull@localhost> | 2016-08-31 13:00:50 +0000 |
commit | 560ea5474c45b3acaea4c3e2fe112f827bbce297 (patch) | |
tree | 5cc2bcebf00152b290849f39a1ab70efad34be62 /sys/src | |
parent | e95082f66c099184afd273d7fc0a30fd2c5e0ba8 (diff) |
pc: add rev function
Diffstat (limited to 'sys/src')
-rw-r--r-- | sys/src/cmd/pc.y | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/sys/src/cmd/pc.y b/sys/src/cmd/pc.y index a890b7ce0..0f456a6eb 100644 --- a/sys/src/cmd/pc.y +++ b/sys/src/cmd/pc.y @@ -804,6 +804,38 @@ fnminv(int, Num **a) return a[0]; } +Num * +fnrev(int, Num **a) +{ + mpdigit v, m; + int i, j, n; + + if(toint(a[1], &n, 1)){ + numdecref(a[0]); + numdecref(a[1]); + return nil; + } + a[0] = nummod(a[0]); + mptrunc(a[0], n, a[0]); + for(i = 0; i < a[0]->top; i++){ + v = a[0]->p[i]; + m = -1; + for(j = sizeof(mpdigit) * 8; j >>= 1; ){ + m ^= m << j; + v = v >> j & m | v << j & ~m; + } + a[0]->p[i] = v; + } + for(i = 0; i < a[0]->top / 2; i++){ + v = a[0]->p[i]; + a[0]->p[i] = a[0]->p[a[0]->top - 1 - i]; + a[0]->p[a[0]->top - 1 - i] = v; + } + mpleft(a[0], n - a[0]->top * sizeof(mpdigit) * 8, a[0]); + numdecref(a[1]); + return a[0]; +} + void main(int argc, char **argv) { @@ -830,6 +862,7 @@ main(int argc, char **argv) regfunc("gcd", fngcd, 2); regfunc("minv", fnminv, 2); regfunc("rand", fnrand, 1); + regfunc("rev", fnrev, 2); prompt = 1; ARGBEGIN{ |