This commit is contained in:
cinap_lenrek 2016-09-19 02:12:18 +02:00
commit f5fcb42cff
2 changed files with 86 additions and 2 deletions

View file

@ -65,6 +65,9 @@ Display \fIn\fR in decimal.
.I hex(n) .I hex(n)
Display \fIn\fR in hexadecimal. Display \fIn\fR in hexadecimal.
.TP .TP
.I pb(n, b)
Display \fIn\fR in base \fIb\fR (currently must be one of 0, 2, 8, 10, 16; 0 uses the defined output base).
.TP
.I abs(n) .I abs(n)
Absolute value of \fIn\fR. Absolute value of \fIn\fR.
.TP .TP
@ -135,6 +138,10 @@ Use Euclidean division (default).
Use truncating division (same as C). Use truncating division (same as C).
\fIa\fR / \fIb\fR is rounded towards zero. \fIa\fR / \fIb\fR is rounded towards zero.
\fIa\fR % \fIb\fR can be negative. \fIa\fR % \fIb\fR can be negative.
.TP
\fL\'\fR 1
Enable numbering bits (disable with 0).
If the base is a power of two, print the number of the corresponding bit above each digit.
.SH SOURCE .SH SOURCE
.B /sys/src/cmd/pc.y .B /sys/src/cmd/pc.y
.SH "SEE ALSO" .SH "SEE ALSO"

View file

@ -7,7 +7,7 @@
#include <thread.h> #include <thread.h>
#include <libsec.h> #include <libsec.h>
int inbase = 10, outbase, divmode, sep, fail, prompt; int inbase = 10, outbase, divmode, sep, heads, fail, prompt;
enum { MAXARGS = 16 }; enum { MAXARGS = 16 };
typedef struct Num Num; typedef struct Num Num;
@ -228,11 +228,38 @@ getsym(char *n, int mk)
return *p; return *p;
} }
static void
printhead(int n, int s, int sp, char *t)
{
char *q;
int i, j, k;
for(i = 1; i < n; i *= 10)
;
while(i /= 10, i != 0){
q = t;
*--q = 0;
for(j = 0, k = 0; j < n; j += s, k++){
if(k == sep && sep != 0){
*--q = ' ';
k = 0;
}
if(j >= i || j == 0 && i == 1)
*--q = '0' + j / i % 10;
else
*--q = ' ';
}
for(j = 0; j < sp; j++)
*--q = ' ';
print("%s\n", q);
}
}
void void
numprint(Num *n) numprint(Num *n)
{ {
int b; int b;
int l, i; int l, i, st, sp;
char *s, *t, *p, *q; char *s, *t, *p, *q;
if(n == nil) return; if(n == nil) return;
@ -246,6 +273,18 @@ numprint(Num *n)
l = strlen(s); l = strlen(s);
t = emalloc(l * 2 + 4); t = emalloc(l * 2 + 4);
q = t + l * 2 + 4; q = t + l * 2 + 4;
if(heads){
switch(b){
case 16: st = 4; sp = 2; break;
case 8: st = 3; sp = 1; break;
case 2: st = 1; sp = 2; break;
default: st = 0; sp = 0;
}
if(n->sign < 0)
sp++;
if(st != 0)
printhead(mpsignif(n), st, sp, q);
}
*--q = 0; *--q = 0;
for(p = s + l - 1, i = 0; p >= s && *p != '-'; p--, i++){ for(p = s + l - 1, i = 0; p >= s && *p != '-'; p--, i++){
if(sep != 0 && i == sep){ if(sep != 0 && i == sep){
@ -409,6 +448,19 @@ stat: { last = nil; }
numdecref(last); numdecref(last);
last = nil; last = nil;
} }
| '\'' { save = inbase; inbase = 10; } expr {
inbase = save;
save = heads;
if(!fail)
heads = mptoi($3);
if(heads != 0 && heads != 1){
error("no.");
heads = save;
}
numdecref($3);
numdecref(last);
last = nil;
}
| error | error
expr: LNUM expr: LNUM
@ -638,6 +690,30 @@ fnbin(int, Num **a)
return r; return r;
} }
Num *
fnpb(int, Num **a)
{
Num *r;
int b;
if(toint(a[1], &b, 1)){
out:
numdecref(a[0]);
numdecref(a[1]);
return nil;
}
if(b != 0 && b != 2 && b != 8 && b != 10 && b != 16){
error("unsupported base");
goto out;
}
r = nummod(a[0]);
if(b == 0)
r->b = 0;
else
r->b = STRONG | b;
return r;
}
Num * Num *
fnabs(int, Num **a) fnabs(int, Num **a)
{ {
@ -903,6 +979,7 @@ main(int argc, char **argv)
regfunc("dec", fndec, 1); regfunc("dec", fndec, 1);
regfunc("oct", fnoct, 1); regfunc("oct", fnoct, 1);
regfunc("bin", fnbin, 1); regfunc("bin", fnbin, 1);
regfunc("pb", fnpb, 2);
regfunc("abs", fnabs, 1); regfunc("abs", fnabs, 1);
regfunc("round", fnround, 2); regfunc("round", fnround, 2);
regfunc("floor", fnfloor, 2); regfunc("floor", fnfloor, 2);