ref: f5fcb42cffce91e8142c6934e398c11c95e907ec
parent: 6d354d07e81aa94b3798603093dfa26fac2f6488
parent: 0c50e1bc3d63f8a62986bbd140f9aef48a0cb076
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Sun Sep 18 22:12:18 EDT 2016
merge
--- a/sys/man/1/pc
+++ b/sys/man/1/pc
@@ -65,6 +65,9 @@
.I hex(n)
Display \fIn\fR in hexadecimal.
.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)
Absolute value of \fIn\fR.
.TP
@@ -135,6 +138,10 @@
Use truncating division (same as C).
\fIa\fR / \fIb\fR is rounded towards zero.
\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
.B /sys/src/cmd/pc.y
.SH "SEE ALSO"
--- a/sys/src/cmd/pc.y
+++ b/sys/src/cmd/pc.y
@@ -7,7 +7,7 @@
#include <thread.h>
#include <libsec.h>
-int inbase = 10, outbase, divmode, sep, fail, prompt;
+int inbase = 10, outbase, divmode, sep, heads, fail, prompt;
enum { MAXARGS = 16 };
typedef struct Num Num;
@@ -228,11 +228,38 @@
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
numprint(Num *n)
{
int b;
- int l, i;
+ int l, i, st, sp;
char *s, *t, *p, *q;
if(n == nil) return;
@@ -246,6 +273,18 @@
l = strlen(s);
t = emalloc(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;
for(p = s + l - 1, i = 0; p >= s && *p != '-'; p--, i++){
if(sep != 0 && i == sep){
@@ -409,6 +448,19 @@
numdecref(last);
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
expr: LNUM
@@ -639,6 +691,30 @@
}
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 *
fnabs(int, Num **a)
{
Num *r;
@@ -903,6 +979,7 @@
regfunc("dec", fndec, 1);
regfunc("oct", fnoct, 1);
regfunc("bin", fnbin, 1);
+ regfunc("pb", fnpb, 2);
regfunc("abs", fnabs, 1);
regfunc("round", fnround, 2);
regfunc("floor", fnfloor, 2);