From 7da3993bfdfb84085e17c440c3a8d600d127469d Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Sat, 7 Jan 2023 18:30:32 -0800 Subject: [PATCH] wip --- silly.js | 58 +++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 39 insertions(+), 19 deletions(-) diff --git a/silly.js b/silly.js index 6b4563a..2dd95b5 100644 --- a/silly.js +++ b/silly.js @@ -4,18 +4,15 @@ let logBits = 8; let logEntries = 2 ** logBits; -let powBits = 19; +let powBits = 16; let powEntries = 2 ** powBits; -// Room to hold powers up to 4 -let shift = 3; +// Room to hold exponents up to 15.9 for 16-bit output +let shift = 4; let base = 2 ** (powBits - shift); -// 16-bit lookup table -let reduction = 7; - -// 12-bit lookup table -//let reduction = 4; +// total of 12-bit lookup table +let reduction = 0; let powCount = powEntries >> reduction; @@ -32,6 +29,9 @@ function toFloat(fixed) { let enloggen = new Uint32Array(logEntries); for (let i = 0; i < logEntries; i++) { enloggen[i] = toFixed(Math.log2(i)); + if (enloggen[i] > 65535) { + throw new Error('enloggen entry out of range') + } } // 64k entries @@ -40,8 +40,10 @@ for (let i = 0; i < logEntries; i++) { // or splitting into high & low vals let empower = new Uint16Array(powCount); for (let i = 0; i < powCount; i++) { - let fixed = i << reduction; - empower[i] = Math.round(2 ** toFloat(fixed)); + empower[i] = Math.round(2 ** toFloat(i << reduction)); + if (empower[i] > 65535) { + throw new Error('empower entry out of range') + } } @@ -52,27 +54,44 @@ function log2(val) { // returns rounded integer function pow2(fixed) { - n = (fixed >> reduction); + let n = fixed >> reduction; + if (empower[n] == undefined) { + console.log(`float ${toFloat(fixed)} fixed ${fixed} n ${n} max ${empower.length}`); + + //throw new Error('whoops'); + } return empower[n]; } function mul(a, b) { if (a == 0) return 0; if (b == 0) return 0; - let la = log2(a); - let lb = log2(b); + let la = log2(a)|0; + let lb = log2(b)|0; + let sum = la + lb; + if (sum >= (2 ** powBits)) { + // overflow + throw new Error('overflow on mul'); + } return pow2(la + lb); } for (let i = 0; i < logEntries; i++) { let l = log2(i); let p = pow2(l); - //console.log(`${i} ${l} ${p}`) + console.log(`${i} ${l} ${p}`) if (i !== p) { - //console.log(`mismatch ${i} expected, got ${p} via log value ${l} (${toFloat(l)})`); + console.log(`mismatch ${i} expected, got ${p} via log value ${l} (${toFloat(l)})`); } } -//process.exit(1); + +console.log('empower'); +for (let i = 0; i < powEntries; i++) { + let fixed = i << reduction; + let float = toFloat(fixed); + let val = pow2(fixed); + console.log(`${i} ${fixed} ${float} ${val}`) +} // now just try multipling numbers @@ -96,17 +115,18 @@ for (let i = 0; i < 65536; i++) { let b = (i >> 8) & 0xff; let expected = a * b; let result = mul(a, b); + console.log(`a ${a} b ${b} expected ${expected} result ${result} loga ${log2(a)} logb ${log2(b)} pow ${pow2(log2(a)+log2(b))}`); let delta = Math.abs(result - expected); let epsilon = 1; - if (delta >= epsilon) { + if (delta >= epsilon || result === undefined) { let percent = 100 * (delta / expected); - //console.log(`${a} * ${b} = ${expected}, but got ${result} delta ${delta} ${Math.round(percent * 100) / 100}%`); + console.log(`${a} * ${b} = ${expected}, but got ${result} delta ${delta} ${Math.round(percent * 100) / 100}%`); deltas += delta; deltaCount++; } else { - //console.log(`${a} * ${b} = ${result}`); + console.log(`${a} * ${b} = ${result}`); } count++; }