summaryrefslogtreecommitdiff
path: root/sys/src/cmd
diff options
context:
space:
mode:
authoraiju <devnull@localhost>2016-08-29 09:57:15 +0200
committeraiju <devnull@localhost>2016-08-29 09:57:15 +0200
commite95082f66c099184afd273d7fc0a30fd2c5e0ba8 (patch)
treedb18fc19118fbb7a34f7dfce3dc5a4f940bdc030 /sys/src/cmd
parenta08bf6831f5122fc9bfc6dccf77096f6ac2e4d03 (diff)
pc: add gcd, rand and minv; set base of logical operation results to 0
Diffstat (limited to 'sys/src/cmd')
-rw-r--r--sys/src/cmd/pc.y59
1 files changed, 49 insertions, 10 deletions
diff --git a/sys/src/cmd/pc.y b/sys/src/cmd/pc.y
index 4549634de..a890b7ce0 100644
--- a/sys/src/cmd/pc.y
+++ b/sys/src/cmd/pc.y
@@ -4,8 +4,8 @@
#include <bio.h>
#include <ctype.h>
#include <mp.h>
-#include <pool.h>
#include <thread.h>
+#include <libsec.h>
int inbase = 10, outbase, divmode, sep, fail, prompt;
enum { MAXARGS = 16 };
@@ -175,12 +175,12 @@ numbin(int op, Num *a, Num *b)
}else
mpasr(a, mptoi(b), a);
break;
- case '<': itomp(mpcmp(a, b) < 0, a); break;
- case '>': itomp(mpcmp(a, b) > 0, a); break;
- case LOLE: itomp(mpcmp(a, b) <= 0, a); break;
- case LOGE: itomp(mpcmp(a, b) >= 0, a); break;
- case LOEQ: itomp(mpcmp(a, b) == 0, a); break;
- case LONE: itomp(mpcmp(a, b) != 0, a); break;
+ case '<': itomp(mpcmp(a, b) < 0, a); a->b = 0; break;
+ case '>': itomp(mpcmp(a, b) > 0, a); a->b = 0; break;
+ case LOLE: itomp(mpcmp(a, b) <= 0, a); a->b = 0; break;
+ case LOGE: itomp(mpcmp(a, b) >= 0, a); a->b = 0; break;
+ case LOEQ: itomp(mpcmp(a, b) == 0, a); a->b = 0; break;
+ case LONE: itomp(mpcmp(a, b) != 0, a); a->b = 0; break;
case LOLAND:
a->b = b->b;
if(mpcmp(a, mpzero) == 0)
@@ -435,7 +435,7 @@ expr: LNUM
| '+' expr %prec unary { $$ = $2; }
| '-' expr %prec unary { $$ = nummod($2); if($$ != nil) mpsub(mpzero, $$, $$); }
| '~' expr %prec unary { $$ = nummod($2); if($$ != nil) mpnot($$, $$); }
- | '!' expr %prec unary { $$ = nummod($2); if($$ != nil) itomp(mpcmp($$, mpzero) == 0, $$); }
+ | '!' expr %prec unary { $$ = nummod($2); if($$ != nil) {itomp(mpcmp($$, mpzero) == 0, $$); $$->b = 0; } }
| expr '?' expr ':' expr %prec '?' {
if($1 == nil || mpcmp($1, mpzero) != 0){
$$ = $3;
@@ -752,7 +752,7 @@ fnubits(int, Num **a)
}
a[0] = nummod(a[0]);
itomp(mpsignif(a[0]), a[0]);
- a[0]->b = 10;
+ a[0]->b = 0;
return a[0];
}
@@ -762,11 +762,47 @@ fnsbits(int, Num **a)
a[0] = nummod(a[0]);
if(a[0]->sign < 0) mpadd(a[0], mpone, a[0]);
itomp(mpsignif(a[0]) + 1, a[0]);
- a[0]->b = 10;
+ a[0]->b = 0;
return a[0];
}
+Num *
+fngcd(int, Num **a)
+{
+ a[0] = nummod(a[0]);
+ a[0]->b = basemax(a[0]->b, a[1]->b);
+ mpextendedgcd(a[0], a[1], a[0], nil, nil);
+ return a[0];
+}
+
+Num *
+fnrand(int, Num **a)
+{
+ Num *n;
+
+ n = numalloc();
+ n->b = a[0]->b;
+ mpnrand(a[0], genrandom, n);
+ numdecref(a[0]);
+ return n;
+}
+
+Num *
+fnminv(int, Num **a)
+{
+ mpint *x;
+ a[0] = nummod(a[0]);
+ x = mpnew(0);
+ mpextendedgcd(a[0], a[1], x, a[0], nil);
+ if(mpcmp(x, mpone) != 0)
+ error("no modular inverse");
+ else
+ mpmod(a[0], a[1], a[0]);
+ mpfree(x);
+ numdecref(a[1]);
+ return a[0];
+}
void
main(int argc, char **argv)
@@ -791,6 +827,9 @@ main(int argc, char **argv)
regfunc("xtend", fnxtend, 2);
regfunc("ubits", fnubits, 1);
regfunc("sbits", fnsbits, 1);
+ regfunc("gcd", fngcd, 2);
+ regfunc("minv", fnminv, 2);
+ regfunc("rand", fnrand, 1);
prompt = 1;
ARGBEGIN{