From a34687ba25ede9445ae0cc440bb5676d3677d281 Mon Sep 17 00:00:00 2001
From: Brion Vibber <brion@pobox.com>
Date: Sat, 7 Jan 2023 20:06:12 -0800
Subject: [PATCH] hmm

---
 silly.js | 36 +++++++++++++++++++++++-------------
 1 file changed, 23 insertions(+), 13 deletions(-)

diff --git a/silly.js b/silly.js
index 4a07fa7..7d854a7 100644
--- a/silly.js
+++ b/silly.js
@@ -1,19 +1,20 @@
 // i/o range: 16 bits
 let bits = 16;
 
-// Room to hold values up to 15.9 for 16-bit mandelbrot
+// max Mandelbrot zx/zy addition range prior to checking distance
+let inputRange = 4;
+
+// Room to hold power up to -12/+4 for 16-bit mandelbrot
 let shift = 4;
 let base = 2 ** (bits - shift);
 
-let inputRange = 8; // max Mandelbrot zx/zy addition range prior to checking distance
-
 let reduction = 0;
 let roundOffset = (2 ** (reduction - 1)) + 1;
 let entries = 2 ** (bits - reduction);
 let bytes = Math.ceil(bits / 8) * entries;
 
 // try to keep all but the last few bits semi-accurate
-let epsilonBits = 2;
+let epsilonBits = 1;
 let epsilon = 2 ** epsilonBits;
 
 function toFixed(float) {
@@ -34,15 +35,15 @@ function toIndex(fixed) {
 }
 
 // x -> log2 x
-let enloggen = new Uint32Array(entries);
+let enloggen = new Int32Array(entries);
 for (let i = 0; i < entries; i++) {
     enloggen[i] = toFixed(Math.log2(toFloat(i << reduction)));
 }
 
 // x -> 2 ^ x
-let empower = new Uint32Array(entries * 2);
+let empower = new Int32Array(entries * 2);
 for (let i = 0; i < entries * 2; i++) {
-    empower[i] = toFixed(2 ** toFloat(i << reduction));
+    empower[i] = toFixed(2 ** toFloat(i - entries << reduction));
 }
 
 
@@ -53,7 +54,11 @@ function log2(fixed) {
 
 // returns rounded integer
 function pow2(fixed) {
-    return empower[toIndex(fixed)];
+    let n = toIndex(fixed);
+    if (n > empower.length) {
+        n = empower.length - 1;
+    }
+    return empower[entries + n];
 }
 
 function mul(a, b) {
@@ -64,7 +69,7 @@ function mul(a, b) {
     let sum = la + lb;
     if (sum >= 2 * entries) {
         // overflow
-        throw new Error('overflow on mul');
+        //throw new Error('overflow on mul');
     }
     return pow2(la + lb);
 }
@@ -104,13 +109,18 @@ while (true) {
 
     let expected = toFixed(toFloat(a) * toFloat(b));
     let result = mul(a, b);
+    if (result === NaN || result === undefined) {
+        console.log(a, b, result);
+        console.log(log2(a), log2(b));
+        throw new Error('invalid');
+    }
 
-    //console.log(`fixed a ${a} b ${b} expected ${expected} result ${result}`);
-    //console.log(`float a ${toFloat(a)} b ${toFloat(b)} expected ${toFloat(expected)} result ${toFloat(result)} loga ${toFloat(log2(a))} logb ${toFloat(log2(b))} pow ${toFloat(pow2(log2(a)+log2(b)))}`);
+    console.log(`fixed a ${a} b ${b} expected ${expected} result ${result} loga ${log2(a)} logb ${log2(b)} sum ${log2(a)+log2(b)} pow ${pow2(log2(a)+log2(b))}`);
+    console.log(`float a ${toFloat(a)} b ${toFloat(b)} expected ${toFloat(expected)} result ${toFloat(result)} loga ${toFloat(log2(a))} logb ${toFloat(log2(b))} sum ${toFloat(log2(a)+log2(b))} pow ${toFloat(pow2(log2(a)+log2(b)))}`);
 
     let delta = Math.abs(result - expected);
 
-    if (delta > 0) {
+    if (delta >= epsilon) {
         let percent = 100 * (delta / expected);
         if (delta > epsilon) {
             console.log(`${toFloat(a)} * ${toFloat(b)} = ${toFloat(expected)}, but got ${toFloat(result)} delta ${toFloat(delta)} ${Math.round(percent * 100) / 100}%`);
@@ -118,7 +128,7 @@ while (true) {
         deltas += delta;
         deltaCount++;
     } else {
-        //console.log(`${toFloat(a)} * ${toFloat(b)} = ${toFloat(result)}`);
+        console.log(`${toFloat(a)} * ${toFloat(b)} = ${toFloat(result)}`);
     }
     count++;
     if (count > 10000) {