From df4600a84251d94634b78fd258378ea0c2269516 Mon Sep 17 00:00:00 2001
From: David Timber <dxdt@dev.snart.me>
Date: Mon, 28 Oct 2024 18:37:47 +0100
Subject: Add writeups/multiprecision

---
 writeups/multiprecision/.gitignore      |   9 +++
 writeups/multiprecision/Makefile        |  46 ++++++++++++++
 writeups/multiprecision/doc/image.webp  | Bin 0 -> 19036 bytes
 writeups/multiprecision/fibo-crude-mp.c | 103 ++++++++++++++++++++++++++++++++
 writeups/multiprecision/fibo.mjs        |  37 ++++++++++++
 writeups/multiprecision/fibo.py         |   9 +++
 writeups/multiprecision/plot            |   2 +
 7 files changed, 206 insertions(+)
 create mode 100644 writeups/multiprecision/.gitignore
 create mode 100644 writeups/multiprecision/Makefile
 create mode 100644 writeups/multiprecision/doc/image.webp
 create mode 100644 writeups/multiprecision/fibo-crude-mp.c
 create mode 100755 writeups/multiprecision/fibo.mjs
 create mode 100755 writeups/multiprecision/fibo.py
 create mode 100644 writeups/multiprecision/plot

diff --git a/writeups/multiprecision/.gitignore b/writeups/multiprecision/.gitignore
new file mode 100644
index 0000000..36a4b95
--- /dev/null
+++ b/writeups/multiprecision/.gitignore
@@ -0,0 +1,9 @@
+/a
+/b
+/c
+/d
+/e
+/fibo-crude-mp
+/sxsdiff-*
+
+*.tmp
diff --git a/writeups/multiprecision/Makefile b/writeups/multiprecision/Makefile
new file mode 100644
index 0000000..cdb10d8
--- /dev/null
+++ b/writeups/multiprecision/Makefile
@@ -0,0 +1,46 @@
+CC ?= cc
+
+all: a b c d e sxsdiff-a-c sxsdiff-c-e fibo-crude-mp
+
+.PHONY: clean doplot all test
+
+clean:
+	rm -f a b c d e fibo-crude-mp sxsdiff-*
+
+a: fibo.py
+	./fibo.py | cat -n > a.tmp
+	mv a.tmp a
+
+b: fibo.mjs
+	./fibo.mjs 1 | cat -n > b.tmp
+	mv b.tmp b
+
+c: fibo.mjs
+	./fibo.mjs 0 | cat -n > c.tmp
+	mv c.tmp c
+
+d: fibo-crude-mp
+	./fibo-crude-mp 1 | cat -n > d.tmp
+	mv d.tmp d
+
+e: fibo-crude-mp
+	./fibo-crude-mp 0 | cat -n > e.tmp
+	mv e.tmp e
+
+test: a b d
+	diff a b
+	diff b d
+
+sxsdiff-a-c: a c
+	! diff --suppress-common-lines -y a c > sxsdiff-a-c.tmp
+	mv sxsdiff-a-c.tmp sxsdiff-a-c
+
+sxsdiff-c-e: c e
+	! diff --suppress-common-lines -y c e > sxsdiff-c-e.tmp
+	mv sxsdiff-c-e.tmp sxsdiff-c-e
+
+doplot: a c e
+	gnuplot plot
+
+fibo-crude-mp: fibo-crude-mp.c
+	$(CC) -std=c99 -Wall -Wextra -g -O0 -o fibo-crude-mp fibo-crude-mp.c
diff --git a/writeups/multiprecision/doc/image.webp b/writeups/multiprecision/doc/image.webp
new file mode 100644
index 0000000..d5c1cf3
Binary files /dev/null and b/writeups/multiprecision/doc/image.webp differ
diff --git a/writeups/multiprecision/fibo-crude-mp.c b/writeups/multiprecision/fibo-crude-mp.c
new file mode 100644
index 0000000..c6a5b7f
--- /dev/null
+++ b/writeups/multiprecision/fibo-crude-mp.c
@@ -0,0 +1,103 @@
+#include <stdio.h>
+#include <stdbool.h>
+#include <string.h>
+#include <assert.h>
+
+#define N 101
+#define MAX_CHAR 256
+
+void do_ieee754 (void) {
+	double a = 0.0;
+	double b = 1.0;
+	double c;
+
+	for (int i = 0; i < N; i += 1) {
+		c = a + b;
+		printf("%.0lf\n", c);
+		b = a;
+		a = c;
+	}
+}
+
+void add (char *out, const char *a, const char *b) {
+	int i;
+	int n;
+	int carry = 0;
+	bool flag;
+
+	for (i = 0; i < MAX_CHAR - 1; i += 1) {
+		n = carry;
+		flag = false;
+		if (a[i] != 0) {
+			n += a[i] - '0';
+			flag = true;
+		}
+		if (b[i] != 0) {
+			n += b[i] - '0';
+			flag = true;
+		}
+		carry = n / 10;
+		if (!flag && carry == 0 && n == 0) {
+			out[i] = 0;
+			return;
+		}
+
+		out[i] = (n % 10) + '0';
+	}
+
+	assert(carry == 0); // detect "overflow"
+}
+
+void print_reversed (const char *s) {
+	const size_t l = strlen(s);
+	const char *p = s + l;
+
+	for (size_t i = 0; i < l; i += 1) {
+		p -= 1;
+		putchar(*p);
+	}
+	putchar('\n');
+}
+
+void do_crude_mp (void) {
+	static char a[MAX_CHAR];
+	static char b[MAX_CHAR];
+	static char c[MAX_CHAR];
+
+	strcpy(a, "0");
+	strcpy(b, "1");
+	memset(c, 0, MAX_CHAR);
+
+	for (int i = 0; i < N; i += 1) {
+		add(c, a, b); // c = a + b;
+		print_reversed(c);
+		memcpy(b, a, MAX_CHAR); // b = a;
+		memcpy(a, c, MAX_CHAR); // a = c;
+	}
+}
+
+bool parse_flag (const char *s) {
+	if (strcmp(s, "true") == 0) {
+		return true;
+	}
+	else if (strcmp(s, "false") == 0) {
+		return false;
+	}
+	else {
+		double tmp = 0.0;
+
+		sscanf(s, "%lf", &tmp);
+		return tmp != 0.0;
+	}
+}
+
+int main (const int argc, const char **argv) {
+	if (argc == 1 || (argc > 1 && parse_flag(argv[1]))) {
+		do_crude_mp();
+	}
+	else {
+		do_ieee754();
+	}
+
+	return 0;
+}
diff --git a/writeups/multiprecision/fibo.mjs b/writeups/multiprecision/fibo.mjs
new file mode 100755
index 0000000..1cc9b10
--- /dev/null
+++ b/writeups/multiprecision/fibo.mjs
@@ -0,0 +1,37 @@
+#!/bin/env node
+
+function do_fibo (num_f) {
+	let a, b, c;
+
+	a = num_f('0');
+	b = num_f('1');
+
+	for (let i = 0; i < 101; i += 1) {
+		c = a + b;
+		console.info(c.toString());
+		b = a;
+		a = c;
+	}
+}
+
+function parse_flag (s) {
+	s = s.toLowerCase();
+
+	if (s === 'true') {
+		return true;
+	}
+	else if (s === 'false') {
+		return false;
+	}
+
+	return Number(s);
+}
+
+const flag = process.argv.length > 2 ? parse_flag(process.argv[2]) : true;
+
+if (flag) {
+	do_fibo(BigInt);
+}
+else {
+	do_fibo(Number);
+}
diff --git a/writeups/multiprecision/fibo.py b/writeups/multiprecision/fibo.py
new file mode 100755
index 0000000..4bddc24
--- /dev/null
+++ b/writeups/multiprecision/fibo.py
@@ -0,0 +1,9 @@
+#!/bin/env python3
+a = 0
+b = 1
+
+for i in range(101):
+	c = a + b
+	print(c)
+	b = a
+	a = c
diff --git a/writeups/multiprecision/plot b/writeups/multiprecision/plot
new file mode 100644
index 0000000..e5232ce
--- /dev/null
+++ b/writeups/multiprecision/plot
@@ -0,0 +1,2 @@
+plot 'a' with lines, 'c' with lines, 'e' with lines
+pause -1
-- 
cgit v1.2.3-70-g09d2