(no commit message)
authorlkcl <lkcl@web>
Wed, 13 Apr 2022 09:07:29 +0000 (10:07 +0100)
committerIkiWiki <ikiwiki.info>
Wed, 13 Apr 2022 09:07:29 +0000 (10:07 +0100)
openpower/sv/bitmanip/appendix.mdwn [new file with mode: 0644]

diff --git a/openpower/sv/bitmanip/appendix.mdwn b/openpower/sv/bitmanip/appendix.mdwn
new file mode 100644 (file)
index 0000000..fffd8c7
--- /dev/null
@@ -0,0 +1,29 @@
+# big integer division
+
+the most efficient division algorithm is probably Knuth's Algorithm D (with modifications from the exercises section of his book) which is O(n^2) and uses 2N-by-N-bit div/rem
+
+an oversimplified version of the knuth algorithm d with 32-bit words is:
+(TODO find original)
+
+```
+void div(uint32_t *n, uint32_t *d, uint32_t* q, int n_bytes, int d_bytes) {
+    // assumes d[0] != 0, also n, d, and q have their most-significant-word in index 0
+    int q_bytes = n_bytes - d_bytes;
+    for(int i = 0; i < q_bytes / sizeof(n[0]); i++) {
+        // calculate guess for quotient word
+        q[i] = (((uint64_t)n[i] << 32) + n[i + 1]) / d[0];
+        // n -= q[i] * d
+        uint32_t carry = 0, carry2 = 0;
+        for(int j = d_bytes / sizeof(d[0]) - 1; j >= 0; j--) {
+            uint64_t v = (uint64_t)q[i] * d[j] + carry;
+            carry = v >> 32;
+            v = (uint32_t)v;
+            v = n[i + j] - v + carry2;
+            carry2 = v >> 32; // either ~0 or 0
+            n[i + j] = v;
+        }
+        // fixup if carry2 != 0
+    }
+    // now remainder is in n and quotient is in q
+}
+```