pc: add gcd, rand and minv; set base of logical operation results to 0
This commit is contained in:
parent
a08bf6831f
commit
e95082f66c
2 changed files with 58 additions and 10 deletions
|
@ -89,6 +89,15 @@ The minimum number of bits required to represent \fIn\fR as an unsigned number.
|
|||
.TP
|
||||
.I sbits(n)
|
||||
The minimum number of bits required to represent \fIn\fR as an signed number.
|
||||
.TP
|
||||
.I gcd(n,m)
|
||||
The greatest common divisor of \fIn\fR and \fIm\fR.
|
||||
.TP
|
||||
.I minv(n,m)
|
||||
The inverse of \fIn\fR mod \fIm\fR.
|
||||
.TP
|
||||
.I rand(n)
|
||||
A random number satisfying 0 ≤ \fIrand(n)\fR < \fIn\fR.
|
||||
.SS Control statements
|
||||
.PP
|
||||
Control statements are always evaluated with default input base 10.
|
||||
|
|
|
@ -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{
|
||||
|
|
Loading…
Reference in a new issue