From a39951d8f69209cfea2b7051832b851914e662ef Mon Sep 17 00:00:00 2001 From: rodri Date: Sat, 22 Feb 2020 09:56:09 +0000 Subject: now version controlled. --- battfmt.c | 28 +++++ beatform.c | 26 ++++ bgetceofindeed.c | 23 ++++ bgetding.c | 46 +++++++ bincoeff.c | 63 ++++++++++ bitround.c | 25 ++++ bracketop.c | 11 ++ colgrad.c | 83 ++++++++++++ consreadnum.c | 17 +++ const.c | 15 +++ constructor.c | 49 ++++++++ dichotomy.c | 36 ++++++ doubleparse.c | 20 +++ dprom.c | 10 ++ dynarray.c | 12 ++ dynsubscript.c | 25 ++++ extorlocal.c | 19 +++ extorlocal.s | 12 ++ extorlocalmain.c | 11 ++ frisvadonb.c | 110 ++++++++++++++++ gcd.c | 68 ++++++++++ genrandname.c | 57 +++++++++ hashing.c | 85 +++++++++++++ hello.c | 9 ++ hypotenuse.c | 59 +++++++++ imgp.c | 8 ++ isptrmod.c | 27 ++++ matrixinv.c | 377 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ matrixmul.c | 53 ++++++++ minhello.c | 9 ++ multibatt.c | 30 +++++ nhello.c | 15 +++ nonrecurfact.c | 58 +++++++++ prec.c | 14 +++ prec2.c | 15 +++ printdec.c | 60 +++++++++ qrot.c | 94 ++++++++++++++ que.c | 70 +++++++++++ ret.c | 19 +++ rev.c | 48 +++++++ revdonewrong.c | 42 +++++++ reverse.c | 42 +++++++ rounding.c | 37 ++++++ rpn.c | 51 ++++++++ seeking.c | 24 ++++ signed.c | 14 +++ sizeof2d.c | 11 ++ smiley.pic | 26 ++++ snprintandf.c | 18 +++ snprinting.c | 13 ++ spranimate.c | 98 +++++++++++++++ strlen.c | 11 ++ structcmp.c | 32 +++++ structvsarray.c | 61 +++++++++ sum.s | 4 + sumain.c | 14 +++ t.c | 48 +++++++ test.c | 14 +++ tok.c | 16 +++ transpose.c | 49 ++++++++ vec.c | 26 ++++ 61 files changed, 2467 insertions(+) create mode 100644 battfmt.c create mode 100644 beatform.c create mode 100644 bgetceofindeed.c create mode 100644 bgetding.c create mode 100644 bincoeff.c create mode 100644 bitround.c create mode 100644 bracketop.c create mode 100644 colgrad.c create mode 100644 consreadnum.c create mode 100644 const.c create mode 100644 constructor.c create mode 100644 dichotomy.c create mode 100644 doubleparse.c create mode 100644 dprom.c create mode 100644 dynarray.c create mode 100644 dynsubscript.c create mode 100644 extorlocal.c create mode 100644 extorlocal.s create mode 100644 extorlocalmain.c create mode 100644 frisvadonb.c create mode 100644 gcd.c create mode 100644 genrandname.c create mode 100644 hashing.c create mode 100644 hello.c create mode 100644 hypotenuse.c create mode 100644 imgp.c create mode 100644 isptrmod.c create mode 100644 matrixinv.c create mode 100644 matrixmul.c create mode 100644 minhello.c create mode 100644 multibatt.c create mode 100644 nhello.c create mode 100644 nonrecurfact.c create mode 100644 prec.c create mode 100644 prec2.c create mode 100644 printdec.c create mode 100644 qrot.c create mode 100644 que.c create mode 100644 ret.c create mode 100644 rev.c create mode 100644 revdonewrong.c create mode 100644 reverse.c create mode 100644 rounding.c create mode 100644 rpn.c create mode 100644 seeking.c create mode 100644 signed.c create mode 100644 sizeof2d.c create mode 100644 smiley.pic create mode 100644 snprintandf.c create mode 100644 snprinting.c create mode 100644 spranimate.c create mode 100644 strlen.c create mode 100644 structcmp.c create mode 100644 structvsarray.c create mode 100644 sum.s create mode 100644 sumain.c create mode 100644 t.c create mode 100644 test.c create mode 100644 tok.c create mode 100644 transpose.c create mode 100644 vec.c diff --git a/battfmt.c b/battfmt.c new file mode 100644 index 0000000..14e0832 --- /dev/null +++ b/battfmt.c @@ -0,0 +1,28 @@ +#include +#include +#include + +void +battfmt(char *buf, long buflen) +{ + char *s; + + for(s = buf; (s-buf) < buflen; s++) + if(!isdigit(*s)){ + for(;(s-buf) < buflen; s++) + *s = '\0'; + break; + } +} + +void +main(void) +{ + char str[] = "30 m"; + + battfmt(str, 4); + + print("%s\n", str); + + exits("done"); +} diff --git a/beatform.c b/beatform.c new file mode 100644 index 0000000..b7ff9f7 --- /dev/null +++ b/beatform.c @@ -0,0 +1,26 @@ +#include +#include + +uvlong +next(uvlong t) +{ + print("t0: %llud ", t); + t = t * 8000 / 44100; + print("t1: %llud ", t); + t = t*(42&t>>10); + print("t2: %llud ", t); + print("t3: %llud ", t<<8); + return t<<8; +} + +void +main() +{ + uvlong t; + short sl; + + for(t = 20000;; t++){ + sl = next(t); + print("%2d\t", sl); + } +} diff --git a/bgetceofindeed.c b/bgetceofindeed.c new file mode 100644 index 0000000..bc79162 --- /dev/null +++ b/bgetceofindeed.c @@ -0,0 +1,23 @@ +#include +#include +#include + +void +main() +{ + Biobuf *bin; + char c; + + bin = Bfdopen(0, OREAD); + if(bin == nil) + sysfatal("Bfdopen: %r"); + while((c = Bgetc(bin)) != Beof) + ; + USED(c); + c = Bgetc(bin); + if(c == Beof) + print("eof indeed\n"); + else + print("no eof after eof\n"); + exits(0); +} diff --git a/bgetding.c b/bgetding.c new file mode 100644 index 0000000..cc427e2 --- /dev/null +++ b/bgetding.c @@ -0,0 +1,46 @@ +#include +#include +#include + +typedef struct +{ + double x, y, z; +} Vec; + +void +usage(void) +{ + fprint(2, "usage: %s [file]\n", argv0); + exits("usage"); +} + +void +main(int argc, char *argv[]) +{ + Biobuf *bin; + Vec v; + int fd, r; + + fd = 0; + ARGBEGIN{ + default: usage(); + }ARGEND; + if(argc > 1) + usage(); + else if(argc == 1){ + fd = open(argv[0], OREAD); + if(fd < 0) + sysfatal("open: %r"); + } + bin = Bfdopen(fd, OREAD); + if(bin == nil) + sysfatal("Bfdopen: %r"); + r = Bgetd(bin, &v.x); + print("got %g r=%d\n", v.x, r); + r = Bgetd(bin, &v.y); + print("got %g r=%d\n", v.y, r); + r = Bgetd(bin, &v.z); + print("got %g r=%d\n", v.z, r); + Bterm(bin); + exits(0); +} diff --git a/bincoeff.c b/bincoeff.c new file mode 100644 index 0000000..624bb19 --- /dev/null +++ b/bincoeff.c @@ -0,0 +1,63 @@ +#include +#include + +vlong t0, Δt; + +double +fac(double n) +{ + double Π; + + Π = 1; + assert(n > 0); + while(n > 1) + Π *= n--; + return Π; +} + +double +bincoeff(double n, double k) +{ + assert(k <= n); + return fac(n)/(fac(k)*fac(n-k)); +} + +double +bincoeffmul(double n, double k) +{ + double Π; + int i; + + assert(k <= n); + Π = 1; + for(i = 1; i <= k; i++) + Π *= (n + 1 - i)/i; + return Π; +} + +void +usage(void) +{ + fprint(2, "usage: bincoeff n k\n"); + exits("usage"); +} + +void +main(int argc, char *argv[]) +{ + double n, k, bc; + + if(argc != 3) + usage(); + n = strtod(argv[1], nil); + k = strtod(argv[2], nil); + t0 = nsec(); + bc = bincoeff(n, k); + Δt = nsec()-t0; + print("method 1: %g (%lldns)\n", bc, Δt); + t0 = nsec(); + bc = bincoeffmul(n, k); + Δt = nsec()-t0; + print("method 2: %g (%lldns)\n", bc, Δt); + exits(nil); +} diff --git a/bitround.c b/bitround.c new file mode 100644 index 0000000..4602387 --- /dev/null +++ b/bitround.c @@ -0,0 +1,25 @@ +#include +#include + +#define round(s, sz) ((s)+((sz)-1)&~((sz)-1)) + +static void +usage(void) +{ + fprint(2, "usage: bitround number\n"); + exits("usage"); +} + +void +main(int argc, char *argv[]) +{ + int i; + + if(argc != 2) + usage(); + i = strtol(argv[1], nil, 0); + print("i0 %b (%d)\n", i, i); + i = round(i, sizeof(int)); + print("i1 %b (%d)\n", i, i); + exits(0); +} diff --git a/bracketop.c b/bracketop.c new file mode 100644 index 0000000..f46849b --- /dev/null +++ b/bracketop.c @@ -0,0 +1,11 @@ +#include +#include + +void +main() +{ + int a[] = {1, 2}; + + print("%d\n", 1[a]); + exits(nil); +} diff --git a/colgrad.c b/colgrad.c new file mode 100644 index 0000000..a122a49 --- /dev/null +++ b/colgrad.c @@ -0,0 +1,83 @@ +#include +#include +#include + +enum { SEC = 1000 }; + +enum { + Cred, + Cgrn, + Cblu, + + Cgx, + Cgy, + Cend +}; +Image *col[Cend]; + +int dx, dy; + +void * +emalloc(ulong n) +{ + void *p; + + p = malloc(n); + if(p == nil) + sysfatal("malloc: %r"); + memset(p, 0, n); + setmalloctag(p, getcallerpc(&n)); + return p; +} + +Image * +eallocimage(Display *d, Rectangle r, ulong chan, int repl, ulong col) +{ + Image *i; + + i = allocimage(d, r, chan, repl, col); + if(i == nil) + sysfatal("allocimage: %r"); + return i; +} + +void +usage(void) +{ + fprint(2, "usage: colgrad\n"); + exits("usage"); +} + +void +main(int argc, char *argv[]) +{ + int i; + uchar *gx, *gy; + + ARGBEGIN{ + default: usage(); + }ARGEND; + + if(initdraw(nil, nil, "colgrad") < 0) + sysfatal("initdraw: %r"); + dx = Dx(screen->r), dy = Dy(screen->r); + col[Cred] = eallocimage(display, Rect(0, 0, 1, 1), RGB24, 1, DRed); + col[Cgrn] = eallocimage(display, Rect(0, 0, 1, 1), RGB24, 1, DGreen); + col[Cblu] = eallocimage(display, Rect(0, 0, 1, 1), RGB24, 1, DBlue); + col[Cgx] = eallocimage(display, Rect(0, 0, dx, 1), GREY8, 1, DNofill); + col[Cgy] = eallocimage(display, Rect(0, 0, 1, dy), GREY8, 1, DNofill); + gx = emalloc(dx); + gy = emalloc(dy); + for(i = 0; i < dx; i++) + gx[i] = 255.0 * i/(dx-1); + for(i = 0; i < dy; i++) + gy[i] = 255.0 * i/(dy-1); + loadimage(col[Cgx], col[Cgx]->r, gx, dx); + loadimage(col[Cgy], col[Cgy]->r, gy, dy); + draw(screen, screen->r, col[Cred], nil, ZP); + draw(screen, screen->r, col[Cgrn], col[Cgx], ZP); + draw(screen, screen->r, col[Cblu], col[Cgy], ZP); + flushimage(display, 1); + sleep(5*SEC); + exits(0); +} diff --git a/consreadnum.c b/consreadnum.c new file mode 100644 index 0000000..2e4f853 --- /dev/null +++ b/consreadnum.c @@ -0,0 +1,17 @@ +#include +#include + +void +main() +{ + char tmp[64]; + int size; + + size = 2*1024*1024*1024; + if(size > sizeof tmp || size < 0) + size = sizeof tmp; + snprint(tmp, sizeof tmp, "%*lud", size-1, 409234UL); + tmp[size-1] = ' '; + print("%s\n", tmp); + exits(nil); +} diff --git a/const.c b/const.c new file mode 100644 index 0000000..8b1e502 --- /dev/null +++ b/const.c @@ -0,0 +1,15 @@ +#include +#include + +char *p = "gooseberry"; +char a[] = "gooseberry"; + +void +main() +{ + print("%s\n%s\n", p, a); + strncpy(p, "black", 5); + strncpy(a, "black", 5); + print("%s\n%s\n", p, a); + exits(nil); +} diff --git a/constructor.c b/constructor.c new file mode 100644 index 0000000..3ecff2d --- /dev/null +++ b/constructor.c @@ -0,0 +1,49 @@ +#include +#include + +typedef struct Point Point; +struct Point +{ + int x, y; +}; + +typedef struct Pointd Pointd; +struct Pointd +{ + double x, y, w; +}; + +Point +Pt(int x, int y) +{ + return (Point){x, y}; +} + +Pointd +Ptd(double x, double y, double w) +{ + return (Pointd){x, y, w}; +} + +vlong t0; + +void +main() +{ + Point p; + Pointd pd; + + t0 = nsec(); + p = (Point){2, 3}; + fprint(2, "p1 %lldnsec\n", nsec()-t0); + t0 = nsec(); + p = Pt(2, 3); + fprint(2, "p2 %lldnsec\n", nsec()-t0); + t0 = nsec(); + pd = (Pointd){2.0, 3.0, 1.0}; + fprint(2, "pd1 %lldnsec\n", nsec()-t0); + t0 = nsec(); + pd = Ptd(2.0, 3.0, 1.0); + fprint(2, "pd2 %lldnsec\n", nsec()-t0); + exits(0); +} diff --git a/dichotomy.c b/dichotomy.c new file mode 100644 index 0000000..5eea1e0 --- /dev/null +++ b/dichotomy.c @@ -0,0 +1,36 @@ +#include +#include + +void * +emalloc(ulong n) +{ + void *p; + + p = malloc(n); + if(p == nil) + sysfatal("malloc: %r"); + memset(p, 0, n); + setmalloctag(p, getcallerpc(&n)); + return p; +} + +char **listp; +char *lista[] = { + "just", + "a", + "couple", + "of", + "words" +}; +char s[] = "ignore this and keep going"; + +void +main() +{ + print("listp size pre-alloc: %d\n", sizeof(listp)); + listp = emalloc(4096); + print("listp size post-alloc: %d\n", sizeof(listp)); + print("lista size: %d & len: %d\n", sizeof(lista), nelem(lista)); + print("s size: %d & len: %ld\n", sizeof(s), strlen(s)); + exits(0); +} diff --git a/doubleparse.c b/doubleparse.c new file mode 100644 index 0000000..497b904 --- /dev/null +++ b/doubleparse.c @@ -0,0 +1,20 @@ +#include +#include +#include + +void +main() +{ + char *s, buf[512]; + double n[2]; + + read(0, buf, sizeof(buf)-1); + buf[sizeof(buf)-1] = 0; + s = buf; + n[0] = strtod(s, &s); + while(isspace(*++s)) + ; + n[1] = strtod(s, &s); + print("n0: %g\nn1: %g\n", n[0], n[1]); + exits(0); +} diff --git a/dprom.c b/dprom.c new file mode 100644 index 0000000..c5d1f58 --- /dev/null +++ b/dprom.c @@ -0,0 +1,10 @@ +#include +#include + +void +main() +{ + if(0.00001 > 0) print("ok\n"); + else print("ko\n"); + exits(0); +} diff --git a/dynarray.c b/dynarray.c new file mode 100644 index 0000000..5b296a1 --- /dev/null +++ b/dynarray.c @@ -0,0 +1,12 @@ +#include +#include + +void +main() +{ + char buf[]; + + buf = malloc(128); + print("%d\n", nelem(buf)); + exits(nil); +} diff --git a/dynsubscript.c b/dynsubscript.c new file mode 100644 index 0000000..e432c22 --- /dev/null +++ b/dynsubscript.c @@ -0,0 +1,25 @@ +#include +#include + +typedef struct Num Num; + +struct Num { + int v; +}; + +Num one = {1}; +Num three = {3}; +Num fourteen = {14}; + +char *list[] = { +[one.v] "ein", +[three.v] "drei", +[fourteen.v] "vierzehn" +}; + +void +main() +{ + print("%s\n", list[one.v]); + exits(0); +} diff --git a/extorlocal.c b/extorlocal.c new file mode 100644 index 0000000..e27f1ae --- /dev/null +++ b/extorlocal.c @@ -0,0 +1,19 @@ +#include +#include + +static char s[] = "hello "; +char t[] = "world\n"; + +void +greet(void) +{ + write(1, s, 6); + write(1, t, 6); +} + +void +main() +{ + greet(); + //exits(0); +} diff --git a/extorlocal.s b/extorlocal.s new file mode 100644 index 0000000..cf63e37 --- /dev/null +++ b/extorlocal.s @@ -0,0 +1,12 @@ +DATA s+0(SB)/8,$"hello wo" +DATA s+8(SB)/4,$"rld\n" +GLOBL s(SB),$13 + +TEXT greet(SB), $32 + MOVL $1, BP + MOVQ $s+0(SB), DI + MOVQ DI, 8(SP) + MOVL $12, DI + MOVL DI, 16(SP) + CALL write(SB) + RET diff --git a/extorlocalmain.c b/extorlocalmain.c new file mode 100644 index 0000000..d23a54d --- /dev/null +++ b/extorlocalmain.c @@ -0,0 +1,11 @@ +#include +#include + +void greet(void); + +void +main() +{ + greet(); + //exits(0); +} diff --git a/frisvadonb.c b/frisvadonb.c new file mode 100644 index 0000000..2eed155 --- /dev/null +++ b/frisvadonb.c @@ -0,0 +1,110 @@ +/* + * Implementation of the techniques described in †. + * + * † Tom Duff, James Burgess, Per Christensen, Christophe Hery, Andrew + * Kensler, Max Liani, and Ryusuke Villemin, Building an Orthonormal + * Basis, Revisited, Journal of Computer Graphics Techniques (JCGT), vol. 6, + * no. 1, 1-8, 2017. Available online at http://jcgt.org/published/0006/01/01/ +*/ + +#include +#include + +typedef struct Vec Vec; +struct Vec { + double x, y, z; +}; + +vlong t0; + +Vec +Vect(double x, double y, double z) +{ + return (Vec){x, y, z}; +} + +void +frisvadONB(Vec b[3]) +{ + double p, q; + + if(b[0].z < -0.9999999){ /* handle singularity */ + b[1] = Vect(0, -1, 0); + b[2] = Vect(-1, 0, 0); + return; + } + p = 1/(1 + b[0].z); + q = -b[0].x*b[0].y*p; + b[1] = Vect(1 - b[0].x*b[0].x*p, q, -b[0].x); + b[2] = Vect(q, 1 - b[0].y*b[0].y*p, -b[0].y); +} + +void +revisedONB(Vec b[3]) +{ + double p, q; + + if(b[0].z < 0){ + p = 1/(1 - b[0].z); + q = b[0].x*b[0].y*p; + b[1] = Vect(1 - b[0].x*b[0].x*p, -q, b[0].x); + b[2] = Vect(q, b[0].y*b[0].y*p - 1, -b[0].y); + return; + } + p = 1/(1 + b[0].z); + q = -b[0].x*b[0].y*p; + b[1] = Vect(1 - b[0].x*b[0].x*p, q, -b[0].x); + b[2] = Vect(q, 1 - b[0].y*b[0].y*p, -b[0].y); +} + +void +revisedaONB(Vec b[3]) +{ + double p, q, σ; + + σ = b[0].z >= 0 ? 1 : -1; + p = -1/(σ + b[0].z); + q = b[0].x*b[0].y*p; + b[1] = Vect(1 + σ*b[0].x*b[0].x*p, σ*q, -σ*b[0].x); + b[2] = Vect(q, σ + b[0].y*b[0].y*p, -b[0].y); +} + +void +usage(void) +{ + fprint(2, "usage: %s x y z\n", argv0); + exits("usage"); +} + +void +main(int argc, char *argv[]) +{ + Vec b[3]; + int i; + + ARGBEGIN{ + default: usage(); + }ARGEND; + if(argc != 3) + usage(); + b[0].x = strtod(argv[0], nil); + b[0].y = strtod(argv[1], nil); + b[0].z = strtod(argv[2], nil); + //b[0] = Vect(0.00038527316, 0.00038460016, -0.99999988079); + t0 = nsec(); + frisvadONB(b); + print("Frisvad's (took %lldns)\n", nsec()-t0); + for(i = 0; i < nelem(b); i++) + print("\tB%d [%g %g %g]\n", i+1, b[i].x, b[i].y, b[i].z); + t0 = nsec(); + revisedONB(b); + print("Revised (took %lldns)\n", nsec()-t0); + for(i = 0; i < nelem(b); i++) + print("\tB%d [%g %g %g]\n", i+1, b[i].x, b[i].y, b[i].z); + t0 = nsec(); + revisedaONB(b); + print("Revised Adv. (took %lldns)\n", nsec()-t0); + for(i = 0; i < nelem(b); i++) + print("\tB%d [%g %g %g]\n", i+1, b[i].x, b[i].y, b[i].z); + exits(nil); +} diff --git a/gcd.c b/gcd.c new file mode 100644 index 0000000..4fa0197 --- /dev/null +++ b/gcd.c @@ -0,0 +1,68 @@ +#include +#include + +enum { + Tgcd, + Tmod, + Te +}; +vlong t[Te]; +vlong t0; + +void +swap(int *a, int *b) +{ + int tmp; + + tmp = *a; + *a = *b; + *b = tmp; +} + +int +gcd(int u, int v) +{ + while(u > 0){ + if(u < v) + swap(&u, &v); + u = u-v; + } + return v; +} + +int +modgcd(int u, int v) +{ + while(u > 0){ + if(u < v) + swap(&u, &v); + u = u % v; + } + return v; +} + +void +usage(void) +{ + fprint(2, "usage: gcd num den\n"); + exits("usage"); +} + +void +main(int argc, char *argv[]) +{ + int n, m; + + if(argc != 3) + sysfatal("not enough arguments"); + n = strtol(argv[1], nil, 0); + m = strtol(argv[2], nil, 0); + t0 = nsec(); + print("GCD %d %d = %d\n", n, m, gcd(n, m)); + t[Tgcd] = nsec()-t0; + t0 = nsec(); + print("MODGCD %d %d = %d\n", n, m, modgcd(n, m)); + t[Tmod] = nsec()-t0; + print("\tgcd: %lld | mod: %lld\n", t[Tgcd], t[Tmod]); + exits(nil); +} diff --git a/genrandname.c b/genrandname.c new file mode 100644 index 0000000..39ce199 --- /dev/null +++ b/genrandname.c @@ -0,0 +1,57 @@ +#include +#include + +enum { + NF, + NM +}; + +typedef struct Name Name; +struct Name +{ + char *name; + int sex; +}; + +void +genrandname(char *d, ulong len) +{ + Name names[] = { + "mariana", NF, + "jerca", NF, + "repa", NF, + "jaca", NF, + "pinta", NF, + "manolo", NM, + "eustaquio", NM, + "aberroncho", NM, + "merovingio", NM, + "trudi", NM + }; + char *adjectives[] = { + "atropelladX", + "bacaladX", + "acojonadX", + "estrictX", + "diarreas", + "gordacX" + }, buf[256], *p; + int i; + + i = ntruerand(nelem(adjectives)); + snprint(buf, sizeof buf, "%s", adjectives[i]); + i = ntruerand(nelem(names)); + if((p = strchr(buf, 'X')) != nil) + *p = names[i].sex == NF ? 'a' : 'o'; + snprint(d, len, "%s%s", names[i].name, buf); +} + +void +main() +{ + char buf[256]; + + genrandname(buf, sizeof buf); + print("%s\n", buf); + exits(0); +} diff --git a/hashing.c b/hashing.c new file mode 100644 index 0000000..32e550f --- /dev/null +++ b/hashing.c @@ -0,0 +1,85 @@ +#include +#include + +enum { + MULT = 31, + NHASH = 37, +}; + +uint +hash(char *s) +{ + uint h; + + h = 0; + while(*s != 0) + h = MULT * h + (uchar)*s++; + return h % NHASH; +} + +uint +djb2(char *s) +{ + uint h; + + h = 5381; + while(*s != 0) + h = ((h << 5) + h) + (uchar)*s++; + return h % NHASH; +} + +uint +djb2a(char *s) +{ + uint h; + + h = 5381; + while(*s != 0) + h = ((h << 5) + h) ^ (uchar)*s++; + return h % NHASH; +} + +uint +fnv1(char *s) +{ + uint h; + + h = 0x811c9dc5; + while(*s != 0) + h = (h*0x1000193) ^ (uchar)*s++; + return h % NHASH; +} + +uint +fnv1a(char *s) +{ + uint h; + + h = 0x811c9dc5; + while(*s != 0) + h = (h^(uchar)*s++) * 0x1000193; + return h % NHASH; +} + +void +usage(void) +{ + fprint(2, "usage: %s word\n", argv0); + exits("usage"); +} + +void +main(int argc, char *argv[]) +{ + ARGBEGIN{ + default: usage(); + }ARGEND; + if(argc != 1) + usage(); + print("tpop:\t%ud\n", hash(*argv)); + print("djb2:\t%ud\n", djb2(*argv)); + print("djb2a:\t%ud\n", djb2a(*argv)); + print("fnv1:\t%ud\n", fnv1(*argv)); + print("fnv1a:\t%ud\n", fnv1a(*argv)); + exits(0); +} diff --git a/hello.c b/hello.c new file mode 100644 index 0000000..852750e --- /dev/null +++ b/hello.c @@ -0,0 +1,9 @@ +#include +#include + +void +main() +{ + print("Hello world\n"); + exits(0); +} diff --git a/hypotenuse.c b/hypotenuse.c new file mode 100644 index 0000000..ab4bb21 --- /dev/null +++ b/hypotenuse.c @@ -0,0 +1,59 @@ +#include +#include + +double +hypot2(double p, double q) +{ + return sqrt(p*p + q*q); +} + +double +hypot3(double x, double y, double z) +{ + return sqrt(x*x + y*y + z*z); +} + +double +hypot3from2(double x, double y, double z) +{ + return hypot(hypot(x, z), y); +} + +void +usage(void) +{ + fprint(2, "usage: hypotenuse x y z\n"); + exits("usage"); +} + +void +main(int argc, char *argv[]) +{ + double x, y, z, r; + vlong t0, t; + + if(argc < 4) + usage(); + x = strtod(argv[1], nil); + y = strtod(argv[2], nil); + z = strtod(argv[3], nil); + /*print("\t2D\n"); + t0 = nsec(); + r = hypot2(x, y); + t = nsec(); + print("1st method: %g (%lld ns)\n", r, t-t0); + t0 = nsec(); + r = hypot(x, y); + t = nsec(); + print("2nd method: %g (%lld ns)\n", r, t-t0); + print("\t3D\n"); + t0 = nsec(); + r = hypot3(x, y, z); + t = nsec(); + print("1st method: %g (%lld ns)\n", r, t-t0);*/ + t0 = nsec(); + r = hypot3from2(x, y, z); + t = nsec(); + print("2nd method: %g (%lld ns)\n", r, t-t0); + exits(0); +} diff --git a/imgp.c b/imgp.c new file mode 100644 index 0000000..200afc4 --- /dev/null +++ b/imgp.c @@ -0,0 +1,8 @@ +#include +#include + +void +main() +{ + +} diff --git a/isptrmod.c b/isptrmod.c new file mode 100644 index 0000000..912a66d --- /dev/null +++ b/isptrmod.c @@ -0,0 +1,27 @@ +#include +#include + +/* + * this program proofs that effectively, pointer arguments are passed by + * value and its modification doesn't extend beyond the scope of the + * currently running procedure. + */ + +void +incptr(char *p) +{ + p += 3; + print("%s\n", p); +} + +void +main() +{ + char *s; + + s = "hi there!"; + print("%s\n", s); + incptr(s); + print("%s\n", s); + exits(0); +} diff --git a/matrixinv.c b/matrixinv.c new file mode 100644 index 0000000..b960c7c --- /dev/null +++ b/matrixinv.c @@ -0,0 +1,377 @@ +#include +#include + +typedef double Matrix[3][3]; +typedef double Matrix3[4][4]; + +void +identity(Matrix m) +{ + memset(m, 0, 3*3*sizeof(double)); + m[0][0] = m[1][1] = m[2][2] = 1; +} + +void +addm(Matrix a, Matrix b) +{ + int i, j; + + for(i = 0; i < 3; i++) + for(j = 0; j < 3; j++) + a[i][j] += b[i][j]; +} + +void +subm(Matrix a, Matrix b) +{ + int i, j; + + for(i = 0; i < 3; i++) + for(j = 0; j < 3; j++) + a[i][j] -= b[i][j]; +} + +void +mulm(Matrix a, Matrix b) +{ + int i, j, k; + Matrix tmp; + + for(i = 0; i < 3; i++) + for(j = 0; j < 3; j++){ + tmp[i][j] = 0; + for(k = 0; k < 3; k++) + tmp[i][j] += a[i][k]*b[k][j]; + } + memmove(a, tmp, 3*3*sizeof(double)); +} + +void +smulm(Matrix m, double s) +{ + int i, j; + + for(i = 0; i < 3; i++) + for(j = 0; j < 3; j++) + m[i][j] *= s; +} + +double +detm(Matrix m) +{ + return m[0][0]*(m[1][1]*m[2][2] - m[1][2]*m[2][1])+ + m[0][1]*(m[1][2]*m[2][0] - m[1][0]*m[2][2])+ + m[0][2]*(m[1][0]*m[2][1] - m[1][1]*m[2][0]); +} + +double +tracem(Matrix m) +{ + return m[0][0] + m[1][1] + m[2][2]; +} + +/* Cayley-Hamilton */ +void +invertm(Matrix m) +{ + Matrix m², r; + double det, trm, trm²; + + det = detm(m); + if(det == 0) + return; /* singular matrices are not invertible */ + trm = tracem(m); + memmove(m², m, 3*3*sizeof(double)); + mulm(m², m²); + trm² = tracem(m²); + identity(r); + smulm(r, (trm*trm - trm²)/2); + smulm(m, trm); + subm(r, m); + addm(r, m²); + smulm(r, 1/det); + memmove(m, r, 3*3*sizeof(double)); +} + +/* Cramer's */ +void +adjm(Matrix m) +{ + Matrix tmp; + + tmp[0][0] = m[1][1]*m[2][2] - m[1][2]*m[2][1]; + tmp[0][1] = -m[0][1]*m[2][2] + m[0][2]*m[2][1]; + tmp[0][2] = m[0][1]*m[1][2] - m[0][2]*m[1][1]; + tmp[1][0] = -m[1][0]*m[2][2] + m[1][2]*m[2][0]; + tmp[1][1] = m[0][0]*m[2][2] - m[0][2]*m[2][0]; + tmp[1][2] = -m[0][0]*m[1][2] + m[0][2]*m[1][0]; + tmp[2][0] = m[1][0]*m[2][1] - m[1][1]*m[2][0]; + tmp[2][1] = -m[0][0]*m[2][1] + m[0][1]*m[2][0]; + tmp[2][2] = m[0][0]*m[1][1] - m[0][1]*m[1][0]; + memmove(m, tmp, 3*3*sizeof(double)); +} + +void +cinvertm(Matrix m) +{ + double det; + + det = detm(m); + if(det == 0) + return; /* singular matrices are not invertible */ + adjm(m); + smulm(m, 1/det); +} + +void +identity3(Matrix3 m) +{ + memset(m, 0, 4*4*sizeof(double)); + m[0][0] = m[1][1] = m[2][2] = m[3][3] = 1; +} + +void +addm3(Matrix3 a, Matrix3 b) +{ + int i, j; + + for(i = 0; i < 4; i++) + for(j = 0; j < 4; j++) + a[i][j] += b[i][j]; +} + +void +subm3(Matrix3 a, Matrix3 b) +{ + int i, j; + + for(i = 0; i < 4; i++) + for(j = 0; j < 4; j++) + a[i][j] -= b[i][j]; +} + +void +mulm3(Matrix3 a, Matrix3 b) +{ + int i, j, k; + Matrix3 tmp; + + for(i = 0; i < 4; i++) + for(j = 0; j < 4; j++){ + tmp[i][j] = 0; + for(k = 0; k < 4; k++) + tmp[i][j] += a[i][k]*b[k][j]; + } + memmove(a, tmp, 4*4*sizeof(double)); +} + +void +smulm3(Matrix3 m, double s) +{ + int i, j; + + for(i = 0; i < 4; i++) + for(j = 0; j < 4; j++) + m[i][j] *= s; +} + +double +detm3(Matrix3 m) +{ + return m[0][0]*(m[1][1]*(m[2][2]*m[3][3] - m[2][3]*m[3][2])+ + m[1][2]*(m[2][3]*m[3][1] - m[2][1]*m[3][3])+ + m[1][3]*(m[2][1]*m[3][2] - m[2][2]*m[3][1])) + -m[0][1]*(m[1][0]*(m[2][2]*m[3][3] - m[2][3]*m[3][2])+ + m[1][2]*(m[2][3]*m[3][0] - m[2][0]*m[3][3])+ + m[1][3]*(m[2][0]*m[3][2] - m[2][2]*m[3][0])) + +m[0][2]*(m[1][0]*(m[2][1]*m[3][3] - m[2][3]*m[3][1])+ + m[1][1]*(m[2][3]*m[3][0] - m[2][0]*m[3][3])+ + m[1][3]*(m[2][0]*m[3][1] - m[2][1]*m[3][0])) + -m[0][3]*(m[1][0]*(m[2][1]*m[3][2] - m[2][2]*m[3][1])+ + m[1][1]*(m[2][2]*m[3][0] - m[2][0]*m[3][2])+ + m[1][2]*(m[2][0]*m[3][1] - m[2][1]*m[3][0])); +} + +double +tracem3(Matrix3 m) +{ + return m[0][0] + m[1][1] + m[2][2] + m[3][3]; +} + +void +adjm3(Matrix3 m) +{ + Matrix3 tmp; + + tmp[0][0]=m[1][1]*(m[2][2]*m[3][3] - m[2][3]*m[3][2])+ + m[2][1]*(m[1][3]*m[3][2] - m[1][2]*m[3][3])+ + m[3][1]*(m[1][2]*m[2][3] - m[1][3]*m[2][2]); + tmp[0][1]=m[0][1]*(m[2][3]*m[3][2] - m[2][2]*m[3][3])+ + m[2][1]*(m[0][2]*m[3][3] - m[0][3]*m[3][2])+ + m[3][1]*(m[0][3]*m[2][2] - m[0][2]*m[2][3]); + tmp[0][2]=m[0][1]*(m[1][2]*m[3][3] - m[1][3]*m[3][2])+ + m[1][1]*(m[0][3]*m[3][2] - m[0][2]*m[3][3])+ + m[3][1]*(m[0][2]*m[1][3] - m[0][3]*m[1][2]); + tmp[0][3]=m[0][1]*(m[1][3]*m[2][2] - m[1][2]*m[2][3])+ + m[1][1]*(m[0][2]*m[2][3] - m[0][3]*m[2][2])+ + m[2][1]*(m[0][3]*m[1][2] - m[0][2]*m[1][3]); + tmp[1][0]=m[1][0]*(m[2][3]*m[3][2] - m[2][2]*m[3][3])+ + m[2][0]*(m[1][2]*m[3][3] - m[1][3]*m[3][2])+ + m[3][0]*(m[1][3]*m[2][2] - m[1][2]*m[2][3]); + tmp[1][1]=m[0][0]*(m[2][2]*m[3][3] - m[2][3]*m[3][2])+ + m[2][0]*(m[0][3]*m[3][2] - m[0][2]*m[3][3])+ + m[3][0]*(m[0][2]*m[2][3] - m[0][3]*m[2][2]); + tmp[1][2]=m[0][0]*(m[1][3]*m[3][2] - m[1][2]*m[3][3])+ + m[1][0]*(m[0][2]*m[3][3] - m[0][3]*m[3][2])+ + m[3][0]*(m[0][3]*m[1][2] - m[0][2]*m[1][3]); + tmp[1][3]=m[0][0]*(m[1][2]*m[2][3] - m[1][3]*m[2][2])+ + m[1][0]*(m[0][3]*m[2][2] - m[0][2]*m[2][3])+ + m[2][0]*(m[0][2]*m[1][3] - m[0][3]*m[1][2]); + tmp[2][0]=m[1][0]*(m[2][1]*m[3][3] - m[2][3]*m[3][1])+ + m[2][0]*(m[1][3]*m[3][1] - m[1][1]*m[3][3])+ + m[3][0]*(m[1][1]*m[2][3] - m[1][3]*m[2][1]); + tmp[2][1]=m[0][0]*(m[2][3]*m[3][1] - m[2][1]*m[3][3])+ + m[2][0]*(m[0][1]*m[3][3] - m[0][3]*m[3][1])+ + m[3][0]*(m[0][3]*m[2][1] - m[0][1]*m[2][3]); + tmp[2][2]=m[0][0]*(m[1][1]*m[3][3] - m[1][3]*m[3][1])+ + m[1][0]*(m[0][3]*m[3][1] - m[0][1]*m[3][3])+ + m[3][0]*(m[0][1]*m[1][3] - m[0][3]*m[1][1]); + tmp[2][3]=m[0][0]*(m[1][3]*m[2][1] - m[1][1]*m[2][3])+ + m[1][0]*(m[0][1]*m[2][3] - m[0][3]*m[2][1])+ + m[2][0]*(m[0][3]*m[1][1] - m[0][1]*m[1][3]); + tmp[3][0]=m[1][0]*(m[2][2]*m[3][1] - m[2][1]*m[3][2])+ + m[2][0]*(m[1][1]*m[3][2] - m[1][2]*m[3][1])+ + m[3][0]*(m[1][2]*m[2][1] - m[1][1]*m[2][2]); + tmp[3][1]=m[0][0]*(m[2][1]*m[3][2] - m[2][2]*m[3][1])+ + m[2][0]*(m[0][2]*m[3][1] - m[0][1]*m[3][2])+ + m[3][0]*(m[0][1]*m[2][2] - m[0][2]*m[2][1]); + tmp[3][2]=m[0][0]*(m[1][2]*m[3][1] - m[1][1]*m[3][2])+ + m[1][0]*(m[0][1]*m[3][2] - m[0][2]*m[3][1])+ + m[3][0]*(m[0][2]*m[1][1] - m[0][1]*m[1][2]); + tmp[3][3]=m[0][0]*(m[1][1]*m[2][2] - m[1][2]*m[2][1])+ + m[1][0]*(m[0][2]*m[2][1] - m[0][1]*m[2][2])+ + m[2][0]*(m[0][1]*m[1][2] - m[0][2]*m[1][1]); + memmove(m, tmp, 4*4*sizeof(double)); +} + +void +invertm3(Matrix3 m) +{ + Matrix3 m², m³, r; + double det, trm, trm², trm³; + + det = detm3(m); + if(det == 0) + return; /* singular matrices are not invertible */ + trm = tracem3(m); + memmove(m³, m, 4*4*sizeof(double)); + mulm3(m³, m³); + mulm3(m³, m); + trm³ = tracem3(m³); + memmove(m², m, 4*4*sizeof(double)); + mulm3(m², m²); + trm² = tracem3(m²); + identity3(r); + smulm3(r, (trm*trm*trm - 3*trm*trm² + 2*trm³)/6); + smulm3(m, (trm*trm - trm²)/2); + smulm3(m², trm); + subm3(r, m); + addm3(r, m²); + subm3(r, m³); + smulm3(r, 1/det); + memmove(m, r, 4*4*sizeof(double)); +} + +void +cinvertm3(Matrix3 m) +{ + double det; + + det = detm3(m); + if(det == 0) + return; /* singular matrices are not invertible */ + adjm3(m); + smulm3(m, 1/det); +} + +void +printm(Matrix m) +{ + int i, j; + + for(i = 0; i < 3; i++){ + for(j = 0; j < 3; j++) + print("\t%g", m[i][j]); + print("\n"); + } +} + +void +printm3(Matrix3 m) +{ + int i, j; + + for(i = 0; i < 4; i++){ + for(j = 0; j < 4; j++) + print("\t%g", m[i][j]); + print("\n"); + } +} + +vlong t0, t; + +void +main() +{ + Matrix m = { + // 7, 2, 1, + // 0, 3, -1, + // -3, 4, -2 + /* near-singular */ + 1, 1, 1, + 0, 1, 0, + 1, 0, 1.01 + }, invm, cinvm; + Matrix3 M = { + 1, 1, 1, -1, + 1, 1, -1, 1, + 1, -1, 1, 1, + -1, 1, 1, 1 + }, invM, cinvM; + + memmove(invm, m, 3*3*sizeof(double)); + memmove(cinvm, m, 3*3*sizeof(double)); + print("M:\n"); + printm(m); + t0 = nsec(); + invertm(invm); + t = nsec()-t0; + print("M⁻¹(%lldns):\n", t); + printm(invm); + t0 = nsec(); + cinvertm(cinvm); + t = nsec()-t0; + print("CM⁻¹(%lldns):\n", t); + printm(cinvm); + mulm(m, invm); + print("MM⁻¹:\n"); + printm(m); + memmove(invM, M, 4*4*sizeof(double)); + memmove(cinvM, M, 4*4*sizeof(double)); + print("M:\n"); + printm3(M); + t0 = nsec(); + invertm3(invM); + t = nsec()-t0; + print("M⁻¹(%lldns):\n", t); + printm3(invM); + t0 = nsec(); + cinvertm3(cinvM); + t = nsec()-t0; + print("CM⁻¹(%lldns):\n", t); + printm3(cinvM); + mulm3(M, invM); + print("MM⁻¹:\n"); + printm3(M); + exits(nil); +} diff --git a/matrixmul.c b/matrixmul.c new file mode 100644 index 0000000..c2da272 --- /dev/null +++ b/matrixmul.c @@ -0,0 +1,53 @@ +#include +#include + +typedef double Matrix[4][4]; + +void +mulm(Matrix a, Matrix b) +{ + int i, j, k; + Matrix r; + + for(i = 0; i < 4; i++) + for(j = 0; j < 4; j++){ + r[i][j] = 0; + for(k = 0; k < 4; k++) + r[i][j] += a[i][k]*b[k][j]; + } + for(i = 0; i < 4; i++) + for(j = 0; j < 4; j++) + a[i][j] = r[i][j]; +} + +void +printm(Matrix m) +{ + int i, j; + + for(i = 0; i < 4; i++){ + for(j = 0; j < 4; j++) + print("%g\t", m[i][j]); + print("\n"); + } +} + +void +main() +{ + Matrix m1 = { + 1, 2, -1, 0, + 2, 0, 1, 0, + 0, 0, 0, 0, + 0, 0, 0, 0 + }; + Matrix m2 = { + 3, 1, 0, 0, + 0, -1, 0, 0, + -2, 3, 0, 0, + 0, 0, 0, 0 + }; + mulm(m1, m2); + printm(m1); + exits(0); +} diff --git a/minhello.c b/minhello.c new file mode 100644 index 0000000..873bc09 --- /dev/null +++ b/minhello.c @@ -0,0 +1,9 @@ +#include +#include + +void +main() +{ + write(1, "Hello world\n", 12); + exits(0); +} diff --git a/multibatt.c b/multibatt.c new file mode 100644 index 0000000..48d27c4 --- /dev/null +++ b/multibatt.c @@ -0,0 +1,30 @@ +#include +#include + +char f[] = "/mnt/acpi/battery"; +char buf[512]; +char *s; +int nb = 0; + +void +main(void) +{ + int fd; + + fd = open(f, OREAD); + if(fd < 0) + sysfatal("open: %r"); + + read(fd, buf, sizeof buf); + + buf[strlen(buf)-1] = '\0'; + + print("%d\n", atoi(buf)); nb++; + for(s = buf; *s != '\0'; s++) + if(*s == '\n'){ + nb++; + print("%d\n", atoi(++s)); + } + print("batteries: %d\n", nb); + exits("done"); +} diff --git a/nhello.c b/nhello.c new file mode 100644 index 0000000..83f07b1 --- /dev/null +++ b/nhello.c @@ -0,0 +1,15 @@ +#include +#include + +char c; +int n; + +void +main() +{ + read(0, &c, 1); + n = c-'0'; + while(n-- > 0) + write(1, "Hola mundo.\n", 12); + exits(0); +} diff --git a/nonrecurfact.c b/nonrecurfact.c new file mode 100644 index 0000000..3fdbf78 --- /dev/null +++ b/nonrecurfact.c @@ -0,0 +1,58 @@ +/* non-recursive factorial */ +#include +#include + +void +printdec(int n) +{ + char s[16], *p; + int r; + + p = s+16; + *--p = '\n'; + for(;;){ + r = n%10; + *--p = '0'+r; + n /= 10; + if(n == 0 || p == s) + break; + } + write(1, p, s+sizeof(s)-p); +} + +int +fact(int n) +{ + int a; + + a = n; +repeat: + if(n <= 0) + return 0; + else if(n == 1) + return a; + a *= --n; + goto repeat; +} + +void +usage(void) +{ + fprint(2, "usage: %s n\n", argv0); + exits("usage"); +} + +void +main(int argc, char *argv[]) +{ + int n; + + ARGBEGIN{ + default: usage(); + }ARGEND; + if(argc != 1) + usage(); + n = strtol(argv[0], nil, 0); + printdec(fact(n)); + exits(0); +} diff --git a/prec.c b/prec.c new file mode 100644 index 0000000..1d25213 --- /dev/null +++ b/prec.c @@ -0,0 +1,14 @@ +#include +#include + +void +main() +{ + char s[] = ",."; + char *p; + + p = s; + while(*p++ == '.' || *p == '.') + print("dot"); + exits(0); +} diff --git a/prec2.c b/prec2.c new file mode 100644 index 0000000..f31bf02 --- /dev/null +++ b/prec2.c @@ -0,0 +1,15 @@ +#include +#include + +void +main() +{ + int n; + int *p; + + n = 4; + p = &n; + print("%d\n", ++*p); + print("%d\n", n); + exits(0); +} diff --git a/printdec.c b/printdec.c new file mode 100644 index 0000000..c061c22 --- /dev/null +++ b/printdec.c @@ -0,0 +1,60 @@ +#include +#include + +void +swap(char *a, char *b) +{ + char tmp; + + tmp = *a; + *a = *b; + *b = tmp; +} + +void +srev(char *s, char *e) +{ + while(s < e) + swap(s++, e--); +} + +void +printdec(int n) +{ + char buf[16]; + char *p, *e; + int r; + + p = buf; + e = buf+sizeof(buf)-1; + while(n > 0 && p < e){ + r = n%10; + *p++ = '0'+r; + n /= 10; + } + *p = 0; + print("%s\n", buf); +} + +void +usage(void) +{ + fprint(2, "usage: %s number\n", argv0); + exits("usage"); +} + +void +main(int argc, char *argv[]) +{ + int n; + + ARGBEGIN{ + default: usage(); + }ARGEND + if(argc != 1) + usage(); + srev(argv[0], argv[0]+strlen(argv[0])-1); + n = strtol(argv[0], nil, 10); + printdec(n); + exits(0); +} diff --git a/qrot.c b/qrot.c new file mode 100644 index 0000000..5da2989 --- /dev/null +++ b/qrot.c @@ -0,0 +1,94 @@ +#include +#include + +#define DEG 0.01745329251994330 + +typedef struct Quaternion Quaternion; +struct Quaternion { + double r, i, j, k; +}; +typedef struct Point3 Point3; +struct Point3 { + double x, y, z, w; +}; + +Point3 +Vec3(double x, double y, double z) +{ + return (Point3){x, y, z, 0}; +} + +Point3 +addpt3(Point3 a, Point3 b) +{ + return (Point3){a.x+b.x, a.y+b.y, a.z+b.z, a.w+b.w}; +} + +Point3 +mulpt3(Point3 p, double s) +{ + return (Point3){p.x*s, p.y*s, p.z*s, p.w*s}; +} + +double +dotvec3(Point3 a, Point3 b) +{ + return a.x*b.x + a.y*b.y + a.z*b.z; +} + +Point3 +crossvec3(Point3 a, Point3 b) +{ + return (Point3){ + a.y*b.z - a.z*b.y, + a.z*b.x - a.x*b.z, + a.x*b.y - a.y*b.x, + 0 + }; +} + +Quaternion +mulq(Quaternion q, Quaternion r) +{ + Point3 qv, rv, tmp; + + qv = Vec3(q.i, q.j, q.k); + rv = Vec3(r.i, r.j, r.k); + tmp = addpt3(addpt3(mulpt3(rv, q.r), mulpt3(qv, r.r)), crossvec3(qv, rv)); + return (Quaternion){q.r*r.r - dotvec3(qv, rv), tmp.x, tmp.y, tmp.z}; +} + +Quaternion +invq(Quaternion q) +{ + double len²; + + len² = q.r*q.r + q.i*q.i + q.j*q.j + q.k*q.k; + if(len² == 0) + return (Quaternion){0, 0, 0, 0}; + return (Quaternion){q.r/len², -q.i/len², -q.j/len², -q.k/len²}; +} + +#pragma varargck type "q" Quaternion +int +qfmt(Fmt *f) +{ + Quaternion q; + + q = va_arg(f->args, Quaternion); + return fmtprint(f, "[%g %g %g %g]", q.r, q.i, q.j, q.k); +} + +void +main() +{ + Quaternion q; + double c, s; + + fmtinstall('q', qfmt); + c = cos(45*DEG); + s = sin(45*DEG); + q = (Quaternion){c, s, s, s}; + print("q %q\nq⁻¹ %q\nqq⁻¹ %q\n", q, invq(q), mulq(q, invq(q))); + exits(nil); +} diff --git a/que.c b/que.c new file mode 100644 index 0000000..9ebee71 --- /dev/null +++ b/que.c @@ -0,0 +1,70 @@ +#include +#include + +typedef struct Node Node; +struct Node { + int n; + Node *next; +}; + +Node *head, *tail; + +void * +emalloc(ulong n) +{ + void *p; + + p = malloc(n); + if(p == nil) + sysfatal("malloc: %r"); + memset(p, 0, n); + setmalloctag(p, getcallerpc(&n)); + return p; +} + +void +put(int n) +{ + if(tail == nil){ + tail = emalloc(sizeof(Node)); + tail->n = n; + head = tail; + return; + } + tail->next = emalloc(sizeof(Node)); + tail = tail->next; + tail->n = n; +} + +int +get(void) +{ + Node *nn; + int n; + + if(head == nil) + return -1; + nn = head->next; + n = head->n; + free(head); + head = nn; + return n; +} + +int +isemtpy(void) +{ + return head == nil; +} + +void +main() +{ + int i; + + for(i = 0; i < 10; i++) + put(i*3); + while(!isemtpy()) + print("%d\n", get()); + exits(nil); +} diff --git a/ret.c b/ret.c new file mode 100644 index 0000000..f49a3d4 --- /dev/null +++ b/ret.c @@ -0,0 +1,19 @@ +#include +#include + +int +ret(void) +{ + if(2 > 3) + return 2; + else + exits("error"); + return -1; +} + +void +main() +{ + ret(); + exits(0); +} diff --git a/rev.c b/rev.c new file mode 100644 index 0000000..6120477 --- /dev/null +++ b/rev.c @@ -0,0 +1,48 @@ +#include +#include + +void +swap(char *a, char *b) +{ + char tmp; + + tmp = *a; + *a = *b; + *b = tmp; +} + +void +rev(char *s, ulong len) +{ + char *e; + + e = s+len; + while(s < e) + swap(s++, --e); +} + +void +usage(void) +{ + fprint(2, "usage: %s text ...\n", argv0); + exits("usage"); +} + +void +main(int argc, char *argv[]) +{ + int first; + + first = 1; + ARGBEGIN{ + default: usage(); + }ARGEND; + if(argc < 1) + usage(); + while(argc--){ + rev(argv[argc], strlen(argv[argc])); + print(first ? first--, "%s" : " %s", argv[argc]); + } + print("\n"); + exits(nil); +} diff --git a/revdonewrong.c b/revdonewrong.c new file mode 100644 index 0000000..d6bb631 --- /dev/null +++ b/revdonewrong.c @@ -0,0 +1,42 @@ +#include +#include + +void +swap(char *a, char *b) +{ + char tmp; + + tmp = *a; + *a = *b; + *b = tmp; +} + +void +rev(char *s, ulong len) +{ + char *e; + + e = s+len; + while(s != e) + swap(s++, --e); +} + +void +usage(void) +{ + fprint(2, "usage: %s text\n", argv0); + exits("usage"); +} + +void +main(int argc, char *argv[]) +{ + ARGBEGIN{ + default: usage(); + }ARGEND; + if(argc != 1) + usage(); + rev(argv[0], strlen(argv[0])); + print("%s\n", argv[0]); + exits(nil); +} diff --git a/reverse.c b/reverse.c new file mode 100644 index 0000000..a038df2 --- /dev/null +++ b/reverse.c @@ -0,0 +1,42 @@ +#include +#include + +char * +reverse(char *s, int n) +{ + int i; + char tmp; + + for(i = 0; i < n/2; i++){ + tmp = s[i]; + s[i] = s[n-i-1]; + s[n-i-1] = tmp; + } + return s; +} + +char * +reversep(char *s, int n) +{ + char *bp, *ep; + char tmp; + + for(bp = s, ep = s+n-1; bp != ep; bp++, ep--){ + tmp = *bp; + *bp = *ep; + *ep = tmp; + } + return s; +} + +void +main() +{ + char s[] = "hello"; + + print("%s → ", s); + print("%s\n", reverse(s, strlen(s))); + print("%s → ", s); + print("%s\n", reversep(s, strlen(s))); + exits(0); +} diff --git a/rounding.c b/rounding.c new file mode 100644 index 0000000..db78664 --- /dev/null +++ b/rounding.c @@ -0,0 +1,37 @@ +#include +#include + +double +roundf(double n) +{ + return floor(n + 0.5); +} + +int +roundi(double n) +{ + return n+0.5; +} + +void +usage(void) +{ + fprint(2, "usage: %s number\n", argv0); + exits("usage"); +} + +void +main(int argc, char *argv[]) +{ + double n; + + ARGBEGIN{ + default: usage(); + }ARGEND; + if(argc != 1) + usage(); + n = strtod(argv[0], nil); + print("%g\n", roundf(n)); + print("%d\n", roundi(n)); + exits(0); +} diff --git a/rpn.c b/rpn.c new file mode 100644 index 0000000..010afde --- /dev/null +++ b/rpn.c @@ -0,0 +1,51 @@ +#include +#include +#include +#include + +int stk[256], sp; +Biobuf *bin; + +void +push(int n) +{ + if(sp >= sizeof stk) + sp = sizeof(stk)-1; + fprint(2, "push [%d] %d\n", sp, n); + stk[sp++] = n; +} + +int +pop(void) +{ + if(sp <= 0) + sp = 1; + fprint(2, "pop [%d] %d\n", sp-1, stk[sp-1]); + return stk[--sp]; +} + +void +main() +{ + int x; + char c; + + bin = Bfdopen(0, OREAD); + if(bin == nil) + sysfatal("Bfdopen: %r"); + while((c = Bgetc(bin)) != Beof){ + x = 0; + switch(c){ + case '+': x = pop() + pop(); break; + case '*': x = pop() * pop(); break; + default: + while(isdigit(c)){ + x = x*10 + c-'0'; + c = Bgetc(bin); + } + } + push(x); + } + print("%d\n", pop()); + exits(nil); +} diff --git a/seeking.c b/seeking.c new file mode 100644 index 0000000..c2f00ed --- /dev/null +++ b/seeking.c @@ -0,0 +1,24 @@ +#include +#include + +#define MAXREADS 3 + +void +main(void) +{ + int fd, i; + char buf[4]; + + fd = open("/mnt/acpi/battery", OREAD); + if(fd < 0) + sysfatal("couldn't open it"); + + for(i = 0; i < MAXREADS; i++){ + pread(fd, buf, sizeof buf, 0); + buf[sizeof(buf)-1] = '\0'; + print(buf); + } + + close(fd); + exits("done"); +} diff --git a/signed.c b/signed.c new file mode 100644 index 0000000..050b66f --- /dev/null +++ b/signed.c @@ -0,0 +1,14 @@ +#include +#include + +void +main() +{ + int x; + + x = 25; + print("n:%d,s:%d\n", x, (x>>31)); + x *= -1; + print("n:%d,s:%d\n", x, (x>>31)); + exits(0); +} diff --git a/sizeof2d.c b/sizeof2d.c new file mode 100644 index 0000000..29bd530 --- /dev/null +++ b/sizeof2d.c @@ -0,0 +1,11 @@ +#include +#include + +void +main() +{ + char m[10][5]; + + print("%d\n", sizeof(m)); + exits(nil); +} diff --git a/smiley.pic b/smiley.pic new file mode 100644 index 0000000..611228d --- /dev/null +++ b/smiley.pic @@ -0,0 +1,26 @@ +.PS +define smiley { + # takes three arguments: x, y and size (radius) + + r0 = $3 # Face + r1 = 0.4*r0 # Radius of mouth and eye locations + r2 = 0.04*r0 # Radius of eyes + +C: circle rad r0 at ( $1, $2 ) + + circle rad r2 filled at last circle + ( r1, r1 ) # Right eye + circle rad r2 filled at 2nd last circle + ( -r1, r1 ) # Left eye + + pi = atan2( 0, -1 ) +S: C + ( r1 * cos(1.25*pi), r1 * sin(1.25*pi) ) + line from S to S + for phi=1.25*pi to 1.75*pi by 0.1 do { + line to C + ( r1 * cos(phi), r1 * sin(phi) ) # Mouth + } +} + +pi2 = 2 * atan2( 0, -1 ) +for x=0.1 to 1.3 by 0.08 do { + smiley( 1.5 * x * cos(x*pi2), 1.1 * x * sin(x*pi2), 0.23 * x ) +} +.PE diff --git a/snprintandf.c b/snprintandf.c new file mode 100644 index 0000000..17707a2 --- /dev/null +++ b/snprintandf.c @@ -0,0 +1,18 @@ +#include +#include +#include + +void +main() +{ + char *s; + int l; + + s = malloc(128); + l = snprint(s, 128, "%s%s", "hi", "there"); + print("%s(%d)\n", s, l); + l = snprintf(s, 128, "%s%s", "hi", "there"); + print("%s(%d)\n", s, l); + free(s); + exits(0); +} diff --git a/snprinting.c b/snprinting.c new file mode 100644 index 0000000..b0a7095 --- /dev/null +++ b/snprinting.c @@ -0,0 +1,13 @@ +#include +#include + +void +main() +{ + char buf[128]; + int n; + + n = snprint(buf, sizeof buf, "%s:%d\n", "actual.out", 2); + print("%d\n", n); + exits(0); +} diff --git a/spranimate.c b/spranimate.c new file mode 100644 index 0000000..347be3c --- /dev/null +++ b/spranimate.c @@ -0,0 +1,98 @@ +#include +#include +#include + +enum { SEC = 1000 }; + +enum { + Cred, + Cgrn, + + Cbg, + + Cgx, + Cend +}; +Image *col[Cend]; + +int dx, dy; + +void * +emalloc(ulong n) +{ + void *p; + + p = malloc(n); + if(p == nil) + sysfatal("malloc: %r"); + memset(p, 0, n); + setmalloctag(p, getcallerpc(&n)); + return p; +} + +Image * +eallocimage(Display *d, Rectangle r, ulong chan, int repl, ulong col) +{ + Image *i; + + i = allocimage(d, r, chan, repl, col); + if(i == nil) + sysfatal("allocimage: %r"); + return i; +} + +void +usage(void) +{ + fprint(2, "usage: spranimate\n"); + exits("usage"); +} + +void +main(int argc, char *argv[]) +{ + Image *spnr, *spnmsk; + double θ; + uchar *gx; + int ds, i, x, y, inc, frame; + + ARGBEGIN{ + default: usage(); + }ARGEND; + + if(initdraw(nil, nil, "spranimate") < 0) + sysfatal("initdraw: %r"); + dx = Dx(screen->r), dy = Dy(screen->r); + col[Cred] = eallocimage(display, Rect(0, 0, 1, 1), RGB24, 1, DRed); + col[Cgrn] = eallocimage(display, Rect(0, 0, 1, 1), RGB24, 1, DGreen); + col[Cbg] = eallocimage(display, Rect(0, 0, 1, 1), RGB24, 1, DNofill); + ds = dx > dy ? dy : dx; + spnr = eallocimage(display, Rect(0, 0, ds*60, ds), RGBA32, 0, DTransparent); + spnmsk = eallocimage(display, Rect(0, 0, ds, ds), GREY1, 0, DWhite); + col[Cgx] = eallocimage(display, Rect(0, 0, 60, 1), GREY8, 1, DNofill); + gx = emalloc(60); + for(i = 0; i < 60; i++) + gx[i] = 255.0 * i/(60-1); + for(i = 0; i < 60; i++){ + θ = 2*PI * i/60; + x = (ds/2 - 5) * cos(θ); + y = (ds/2 - 5) * sin(θ); + line(spnr, Pt(x + ds/2 + ds*i, y + ds/2), Pt(-x + ds/2 + ds*i, -y + ds/2), Endarrow, Endsquare, 1, display->black, ZP); + } + loadimage(col[Cgx], col[Cgx]->r, gx, dx); + x = inc = frame = 0; + for(;;){ + draw(col[Cbg], col[Cbg]->r, col[Cred], nil, ZP); + if(x == 0) + inc = 1; + else if(x == 60-1) + inc = -1; + x += inc; + gendraw(col[Cbg], col[Cbg]->r, col[Cgrn], ZP, col[Cgx], Pt(x, 0)); + draw(screen, screen->r, col[Cbg], nil, ZP); + frame = (frame+1) % 60; + gendraw(screen, screen->r, spnr, Pt(frame*ds, 0), spnmsk, ZP); + flushimage(display, 1); + sleep(SEC/60); + } +} diff --git a/strlen.c b/strlen.c new file mode 100644 index 0000000..efc063f --- /dev/null +++ b/strlen.c @@ -0,0 +1,11 @@ +#include +#include + +void +main() +{ + char txt[] = "i'm here now\n"; + + print("len: %ld, lastchar: %c\n", strlen(txt), txt[strlen(txt)-1]); + exits(nil); +} diff --git a/structcmp.c b/structcmp.c new file mode 100644 index 0000000..c1f28c1 --- /dev/null +++ b/structcmp.c @@ -0,0 +1,32 @@ +#include +#include + +enum { + A = 1, + B = 2, + C = 4, + D = 8 +}; + +typedef struct Fruit Fruit; +struct Fruit { + char *name; + int vitamins; +}; + +void +main() +{ + Fruit apple, lemon, apple2; + + apple = (Fruit){"apple", C}; + lemon = (Fruit){"lemon", B|C}; + apple2 = (Fruit){"apple", C}; + if(apple == apple) + fprint(2, "apple equals apple\n"); + if(apple == apple2) + fprint(2, "apple equals apple2\n"); + if(apple == lemon) + fprint(2, "apple equals lemon, really?\n"); + exits(0); +} diff --git a/structvsarray.c b/structvsarray.c new file mode 100644 index 0000000..2f2ddaa --- /dev/null +++ b/structvsarray.c @@ -0,0 +1,61 @@ +#include +#include + +enum { + Ts, + Tp, + Ta, + Tend +}; + +typedef struct Vec Vec; +struct Vec { + double x, y, z; +}; + +typedef double Veca[3]; + +vlong t[Tend], t0; + +Vec +addvec(Vec a, Vec b) +{ + return (Vec){a.x+b.x, a.y+b.y, a.z+b.z}; +} + +void +addvecp(Vec *a, Vec *b) +{ + a->x += b->x; + a->y += b->y; + a->z += b->z; +} + +void +addveca(Veca a, Veca b) +{ + a[0] += b[0]; + a[1] += b[1]; + a[2] += b[2]; +} + +void +main() +{ + Vec a = {5, 2, 19}; + Vec b = {213, 30, -12}; + Veca aa = {2, 9, -1}; + Veca ab = {-10, 20, 30}; + + t0 = nsec(); + a = addvec(a, b); + t[Ts] = nsec()-t0; + t0 = nsec(); + addvecp(&a, &b); + t[Tp] = nsec()-t0; + t0 = nsec(); + addveca(aa, ab); + t[Ta] = nsec()-t0; + print("struct\t%lldns\nstruct*\t%lldns\narray\t%lldns\n", t[Ts], t[Tp], t[Ta]); + exits(nil); +} diff --git a/sum.s b/sum.s new file mode 100644 index 0000000..c89ee30 --- /dev/null +++ b/sum.s @@ -0,0 +1,4 @@ +TEXT sum(SB), $0 + MOVL b+8(FP), AX + ADDL BP, AX + RET diff --git a/sumain.c b/sumain.c new file mode 100644 index 0000000..8db2ab2 --- /dev/null +++ b/sumain.c @@ -0,0 +1,14 @@ +#include +#include + +int sum(int, int); + +void +main() +{ + int n; + + n = sum(24, 30); + print("Σ = %d\n", n); + exits(nil); +} diff --git a/t.c b/t.c new file mode 100644 index 0000000..dcc1814 --- /dev/null +++ b/t.c @@ -0,0 +1,48 @@ +#include +#include +#include +#include + +Channel *spamchan; + +void +freethread(void *) +{ + char *v = nil; + + threadsetname("freethread"); +Loop: + recv(spamchan, &v); + if(v == nil){ + print("nothing to free\n"); + threadexitsall(0); + } + print("freeing %s\n", v); + free(v); + goto Loop; +} + +void +spammer(void*) +{ + int i; + char *s; + + threadsetname("spammer"); + for(i = 0; i < 10; ++i){ + s = smprint("%d", i); + send(spamchan, &s); + } + send(spamchan, nil); +} + +void +threadmain(int argc, char *argv[]) +{ + print("acid -l thread %d\n", getpid()); + threadsetname("main"); + spamchan = chancreate(sizeof(char*), 0); + threadcreate(spammer, nil, 8192); + threadcreate(freethread, nil, 8192); + yield(); +} diff --git a/test.c b/test.c new file mode 100644 index 0000000..70040c1 --- /dev/null +++ b/test.c @@ -0,0 +1,14 @@ +#include +#include + +void +greet(void) +{ + write(1, "hello world\n", 12); +} + +void +main() +{ + greet(); +} diff --git a/tok.c b/tok.c new file mode 100644 index 0000000..f4ced82 --- /dev/null +++ b/tok.c @@ -0,0 +1,16 @@ +#include +#include + +void +main() +{ + char buf[256], *f[10]; + int nf, i; + + while(read(0, buf, sizeof(buf)-1) > 0){ + nf = tokenize(buf, f, nelem(f)); + for(i = 0; i < nf; i++) + fprint(2, "%d: %s\n", i, f[i]); + } + exits(0); +} diff --git a/transpose.c b/transpose.c new file mode 100644 index 0000000..ee607f6 --- /dev/null +++ b/transpose.c @@ -0,0 +1,49 @@ +#include +#include + +#define N 4 + +typedef double Matrix[N][N]; + +void +transpose(Matrix a) +{ + int i, j; + double tmp; + + for(i = 0; i < N; i++) + for(j = i; j < N; j++){ + tmp = a[i][j]; + a[i][j] = a[j][i]; + a[j][i] = tmp; + } +} + +void +printm(Matrix m) +{ + int i, j; + + for(i = 0; i < N; i++){ + for(j = 0; j < N; j++) + print("%g ", m[i][j]); + print("\n"); + } + print("\n"); +} + +void +main() +{ + Matrix m = { + 11, 12, 13, 14, + 21, 22, 23, 24, + 31, 32, 33, 34, + 41, 42, 43, 44, + }; + + printm(m); + transpose(m); + printm(m); + exits(0); +} diff --git a/vec.c b/vec.c new file mode 100644 index 0000000..74ccc5a --- /dev/null +++ b/vec.c @@ -0,0 +1,26 @@ +#include +#include + +typedef struct Vec Vec; +struct Vec { + double x, y, z; +}; + +Vec +addvec(Vec a, Vec b) +{ + a.x += b.x; + a.y += b.y; + a.z += b.z; + return a; +} + +void +main() +{ + Vec a = {20, 5, 3}; + Vec b = {6, -2, 19}; + + a = addvec(a, b); + exits(nil); +} -- cgit v1.2.3