From 49831dc04846831649fdc1e059e38b79bdfcce93 Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Sat, 7 Jan 2023 17:20:18 -0800 Subject: [PATCH 01/10] wip logs --- silly.js | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 silly.js diff --git a/silly.js b/silly.js new file mode 100644 index 0000000..defd097 --- /dev/null +++ b/silly.js @@ -0,0 +1,94 @@ +// input range: 0..255 * 0..255 +// output range: 16 bits + +let logBits = 8; +let logEntries = 2 ** logBits; + +let powBits = 16; +let powEntries = (2 ** powBits); + +// Room to hold powers up to 4 +let shift = 4; +let base = 2 ** (powBits - shift); + +// 16-bit lookup table +// 12-bit lookup table +let reduction = 4; + +function toFixed(float) { + return Math.round(float * base); +} + +function toFloat(fixed) { + return fixed / base; +} + +// 256x2 = 512 bytes +let enloggen = new Uint16Array(logEntries); +for (let i = 0; i < logEntries; i++) { + enloggen[i] = toFixed(Math.log2(i)); +} + +// 64k entries +// 64kx2 = 128 KiB +// can reduce number by reducing precision +// or splitting into high & low vals +let powCount = powEntries >> reduction; +let empower = new Uint16Array(powCount); +for (let i = 0; i < powCount; i++) { + let fixed = i << reduction; + empower[i] = Math.round(2 ** toFloat(fixed)); +} + + +// returns fixed +function log2(byte) { + return enloggen[byte]; +} + +// returns 16-bit number +function pow2(fixed) { + n = (fixed >> reduction); + 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); + return pow2(la + lb); +} + +/* +for (let i = 0; i < logEntries; i++) { + let l = log2(i); + let p = pow2(l); + console.log(`${i} ${l} ${p}`) + if (i !== p) { + //console.log(`mismatch ${i} expected, got ${p} via log value ${l} (${toFloat(l)})`); + } +} +process.exit(1); +*/ + +// now just try multipling numbers +while (true) { + let a = Math.trunc(Math.random() * logEntries); + let b = Math.trunc(Math.random() * logEntries); + + let pExpected = a * b; + let p = mul(a, b); + + let delta = Math.abs(p - pExpected); + let epsilon = 1; + + if (delta >= epsilon) { + let percent = 100 * (delta / pExpected); + console.log(`${a} * ${b} = ${pExpected}, but got ${p} delta ${delta} ${Math.round(percent * 100) / 100}%`); + } else { + console.log(`${a} * ${b} = ${p}`); + } +} + +console.log('done'); From d32b630320223b3ec6b67a00c463996ed96c6399 Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Sat, 7 Jan 2023 17:32:38 -0800 Subject: [PATCH 02/10] woo --- silly.js | 36 ++++++++++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/silly.js b/silly.js index defd097..9d80ee8 100644 --- a/silly.js +++ b/silly.js @@ -12,8 +12,10 @@ let shift = 4; let base = 2 ** (powBits - shift); // 16-bit lookup table +let reduction = 0; + // 12-bit lookup table -let reduction = 4; +//let reduction = 4; function toFixed(float) { return Math.round(float * base); @@ -73,21 +75,39 @@ process.exit(1); */ // now just try multipling numbers +let deltas = 0; +let count = 0; +let deltaCount = 0; +let results = 0; + +function round(n, x) { + return Math.round(x * n) / n; +} + while (true) { let a = Math.trunc(Math.random() * logEntries); let b = Math.trunc(Math.random() * logEntries); + let expected = a * b; + let result = mul(a, b); - let pExpected = a * b; - let p = mul(a, b); - - let delta = Math.abs(p - pExpected); + let delta = Math.abs(result - expected); let epsilon = 1; if (delta >= epsilon) { - let percent = 100 * (delta / pExpected); - console.log(`${a} * ${b} = ${pExpected}, but got ${p} delta ${delta} ${Math.round(percent * 100) / 100}%`); + let percent = 100 * (delta / expected); + //console.log(`${a} * ${b} = ${expected}, but got ${result} delta ${delta} ${Math.round(percent * 100) / 100}%`); + deltas += delta; + deltaCount++; } else { - console.log(`${a} * ${b} = ${p}`); + //console.log(`${a} * ${b} = ${result}`); + } + count++; + if (count == 100) { + deltaAvg = deltas / deltaCount; + console.log(`${count - deltaCount} of ${count} ok -- ${deltaCount} off by avg ${round(10,deltaAvg)})`); + count = 0; + deltas = 0; + deltaCount = 0; } } From a6c49a2ef920a7fb4cee7181d3bad6206851944d Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Sat, 7 Jan 2023 17:52:14 -0800 Subject: [PATCH 03/10] oh ho --- silly.js | 58 ++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 37 insertions(+), 21 deletions(-) diff --git a/silly.js b/silly.js index 9d80ee8..6b4563a 100644 --- a/silly.js +++ b/silly.js @@ -4,19 +4,22 @@ let logBits = 8; let logEntries = 2 ** logBits; -let powBits = 16; -let powEntries = (2 ** powBits); +let powBits = 19; +let powEntries = 2 ** powBits; // Room to hold powers up to 4 -let shift = 4; +let shift = 3; let base = 2 ** (powBits - shift); // 16-bit lookup table -let reduction = 0; +let reduction = 7; // 12-bit lookup table //let reduction = 4; +let powCount = powEntries >> reduction; + + function toFixed(float) { return Math.round(float * base); } @@ -26,7 +29,7 @@ function toFloat(fixed) { } // 256x2 = 512 bytes -let enloggen = new Uint16Array(logEntries); +let enloggen = new Uint32Array(logEntries); for (let i = 0; i < logEntries; i++) { enloggen[i] = toFixed(Math.log2(i)); } @@ -35,7 +38,6 @@ for (let i = 0; i < logEntries; i++) { // 64kx2 = 128 KiB // can reduce number by reducing precision // or splitting into high & low vals -let powCount = powEntries >> reduction; let empower = new Uint16Array(powCount); for (let i = 0; i < powCount; i++) { let fixed = i << reduction; @@ -43,12 +45,12 @@ for (let i = 0; i < powCount; i++) { } -// returns fixed -function log2(byte) { - return enloggen[byte]; +// returns fixed point +function log2(val) { + return enloggen[val]; } -// returns 16-bit number +// returns rounded integer function pow2(fixed) { n = (fixed >> reduction); return empower[n]; @@ -62,17 +64,16 @@ function mul(a, b) { 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)})`); } } -process.exit(1); -*/ +//process.exit(1); + // now just try multipling numbers let deltas = 0; @@ -84,9 +85,15 @@ function round(n, x) { return Math.round(x * n) / n; } +/* while (true) { let a = Math.trunc(Math.random() * logEntries); let b = Math.trunc(Math.random() * logEntries); +*/ + +for (let i = 0; i < 65536; i++) { + let a = i & 0xff; + let b = (i >> 8) & 0xff; let expected = a * b; let result = mul(a, b); @@ -102,13 +109,22 @@ while (true) { //console.log(`${a} * ${b} = ${result}`); } count++; - if (count == 100) { - deltaAvg = deltas / deltaCount; - console.log(`${count - deltaCount} of ${count} ok -- ${deltaCount} off by avg ${round(10,deltaAvg)})`); - count = 0; - deltas = 0; - deltaCount = 0; - } } +deltaAvg = deltas / deltaCount; +console.log(`${count - deltaCount} of ${count} ok -- ${deltaCount} off by avg ${round(10,deltaAvg)})`); +count = 0; +deltas = 0; +deltaCount = 0; + console.log('done'); + + +console.log(`size of enloggen table: ${enloggen.length} entries, ${enloggen.length * 3} bytes`); +console.log(`size of empower table: ${empower.length} entries, ${empower.length * 2} bytes`); + +let m = 0; +for (let i = 0; i < enloggen.length; i++) { + m = Math.max(m, enloggen[i]); +} +console.log(`max enloggen entry is ${m}`); From 7da3993bfdfb84085e17c440c3a8d600d127469d Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Sat, 7 Jan 2023 18:30:32 -0800 Subject: [PATCH 04/10] 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++; } From fe23193ce97e2df6391436bfdcb05dc67ac7ea7a Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Sat, 7 Jan 2023 18:33:06 -0800 Subject: [PATCH 05/10] woot this one works but is too huge --- silly.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/silly.js b/silly.js index 2dd95b5..26b2501 100644 --- a/silly.js +++ b/silly.js @@ -4,7 +4,7 @@ let logBits = 8; let logEntries = 2 ** logBits; -let powBits = 16; +let powBits = 21; let powEntries = 2 ** powBits; // Room to hold exponents up to 15.9 for 16-bit output @@ -29,7 +29,7 @@ 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) { + if (enloggen[i] > powEntries) { throw new Error('enloggen entry out of range') } } @@ -41,7 +41,7 @@ for (let i = 0; i < logEntries; i++) { let empower = new Uint16Array(powCount); for (let i = 0; i < powCount; i++) { empower[i] = Math.round(2 ** toFloat(i << reduction)); - if (empower[i] > 65535) { + if (empower[i] > (logEntries * logEntries)) { throw new Error('empower entry out of range') } } From badc730f2bcbac411bffa313a1480a6009f066c0 Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Sat, 7 Jan 2023 18:37:55 -0800 Subject: [PATCH 06/10] definitely too long :D --- silly.js | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/silly.js b/silly.js index 26b2501..72a4c31 100644 --- a/silly.js +++ b/silly.js @@ -55,10 +55,14 @@ function log2(val) { // returns rounded integer function pow2(fixed) { let n = fixed >> reduction; - if (empower[n] == undefined) { - console.log(`float ${toFloat(fixed)} fixed ${fixed} n ${n} max ${empower.length}`); + if (n >= empower.length) { + /* + console.log(`ERROR float ${toFloat(fixed)} fixed ${fixed} n ${n} max ${empower.length}`); - //throw new Error('whoops'); + throw new Error('whoops'); + */ + // Overflow? Round down. + return empower[empower.length - 1]; } return empower[n]; } @@ -76,6 +80,7 @@ function mul(a, b) { return pow2(la + lb); } +/* for (let i = 0; i < logEntries; i++) { let l = log2(i); let p = pow2(l); @@ -92,7 +97,7 @@ for (let i = 0; i < powEntries; i++) { let val = pow2(fixed); console.log(`${i} ${fixed} ${float} ${val}`) } - +*/ // now just try multipling numbers let deltas = 0; From 38005a6f7d30f4ab89f7d3438cd954c75d06b938 Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Sat, 7 Jan 2023 19:36:11 -0800 Subject: [PATCH 07/10] hmm --- silly.js | 114 +++++++++++++++++++++++++------------------------------ 1 file changed, 52 insertions(+), 62 deletions(-) diff --git a/silly.js b/silly.js index 72a4c31..4a07fa7 100644 --- a/silly.js +++ b/silly.js @@ -1,21 +1,20 @@ -// input range: 0..255 * 0..255 -// output range: 16 bits +// i/o range: 16 bits +let bits = 16; -let logBits = 8; -let logEntries = 2 ** logBits; - -let powBits = 21; -let powEntries = 2 ** powBits; - -// Room to hold exponents up to 15.9 for 16-bit output +// Room to hold values up to 15.9 for 16-bit mandelbrot let shift = 4; -let base = 2 ** (powBits - shift); +let base = 2 ** (bits - shift); + +let inputRange = 8; // max Mandelbrot zx/zy addition range prior to checking distance -// total of 12-bit lookup table let reduction = 0; +let roundOffset = (2 ** (reduction - 1)) + 1; +let entries = 2 ** (bits - reduction); +let bytes = Math.ceil(bits / 8) * entries; -let powCount = powEntries >> reduction; - +// try to keep all but the last few bits semi-accurate +let epsilonBits = 2; +let epsilon = 2 ** epsilonBits; function toFixed(float) { return Math.round(float * base); @@ -25,46 +24,36 @@ function toFloat(fixed) { return fixed / base; } -// 256x2 = 512 bytes -let enloggen = new Uint32Array(logEntries); -for (let i = 0; i < logEntries; i++) { - enloggen[i] = toFixed(Math.log2(i)); - if (enloggen[i] > powEntries) { - throw new Error('enloggen entry out of range') +function toIndex(fixed) { + let n = (fixed + roundOffset) >> reduction; + if (n == entries) { + // round down for the maxo for now + n--; } + return n; } -// 64k entries -// 64kx2 = 128 KiB -// can reduce number by reducing precision -// or splitting into high & low vals -let empower = new Uint16Array(powCount); -for (let i = 0; i < powCount; i++) { - empower[i] = Math.round(2 ** toFloat(i << reduction)); - if (empower[i] > (logEntries * logEntries)) { - throw new Error('empower entry out of range') - } +// x -> log2 x +let enloggen = new Uint32Array(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); +for (let i = 0; i < entries * 2; i++) { + empower[i] = toFixed(2 ** toFloat(i << reduction)); } // returns fixed point -function log2(val) { - return enloggen[val]; +function log2(fixed) { + return enloggen[toIndex(fixed)]; } // returns rounded integer function pow2(fixed) { - let n = fixed >> reduction; - if (n >= empower.length) { - /* - console.log(`ERROR float ${toFloat(fixed)} fixed ${fixed} n ${n} max ${empower.length}`); - - throw new Error('whoops'); - */ - // Overflow? Round down. - return empower[empower.length - 1]; - } - return empower[n]; + return empower[toIndex(fixed)]; } function mul(a, b) { @@ -73,7 +62,7 @@ function mul(a, b) { let la = log2(a)|0; let lb = log2(b)|0; let sum = la + lb; - if (sum >= (2 ** powBits)) { + if (sum >= 2 * entries) { // overflow throw new Error('overflow on mul'); } @@ -101,43 +90,44 @@ for (let i = 0; i < powEntries; i++) { // now just try multipling numbers let deltas = 0; -let count = 0; +let deltaAvg = 0; let deltaCount = 0; -let results = 0; +let count = 0; function round(n, x) { return Math.round(x * n) / n; } -/* while (true) { - let a = Math.trunc(Math.random() * logEntries); - let b = Math.trunc(Math.random() * logEntries); -*/ + let a = toFixed(Math.random() * inputRange); + let b = toFixed(Math.random() * inputRange); -for (let i = 0; i < 65536; i++) { - let a = i & 0xff; - let b = (i >> 8) & 0xff; - let expected = a * b; + let expected = toFixed(toFloat(a) * toFloat(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))}`); + + //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)))}`); let delta = Math.abs(result - expected); - let epsilon = 1; - if (delta >= epsilon || result === undefined) { + if (delta > 0) { let percent = 100 * (delta / expected); - console.log(`${a} * ${b} = ${expected}, but got ${result} delta ${delta} ${Math.round(percent * 100) / 100}%`); + if (delta > epsilon) { + console.log(`${toFloat(a)} * ${toFloat(b)} = ${toFloat(expected)}, but got ${toFloat(result)} delta ${toFloat(delta)} ${Math.round(percent * 100) / 100}%`); + } deltas += delta; deltaCount++; } else { - console.log(`${a} * ${b} = ${result}`); + //console.log(`${toFloat(a)} * ${toFloat(b)} = ${toFloat(result)}`); } count++; + if (count > 10000) { + break; + } } -deltaAvg = deltas / deltaCount; -console.log(`${count - deltaCount} of ${count} ok -- ${deltaCount} off by avg ${round(10,deltaAvg)})`); +deltaAvg = deltas / count; +console.log(`${count - deltaCount} of ${count} ok -- ${deltaCount} off by avg ${toFloat(deltaAvg)} -- fixed ${round(10,deltaAvg)}`); count = 0; deltas = 0; deltaCount = 0; @@ -145,8 +135,8 @@ deltaCount = 0; console.log('done'); -console.log(`size of enloggen table: ${enloggen.length} entries, ${enloggen.length * 3} bytes`); -console.log(`size of empower table: ${empower.length} entries, ${empower.length * 2} bytes`); +console.log(`size of enloggen table: ${entries * 2} entries, ${bytes} bytes`); +console.log(`size of empower table: ${entries * 2} entries, ${bytes * 2} bytes`); let m = 0; for (let i = 0; i < enloggen.length; i++) { From a34687ba25ede9445ae0cc440bb5676d3677d281 Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Sat, 7 Jan 2023 20:06:12 -0800 Subject: [PATCH 08/10] 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) { From f1adffd175c7f24d82f182fe86dc76ae8546168f Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Sat, 7 Jan 2023 20:11:52 -0800 Subject: [PATCH 09/10] asdlijf --- silly.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/silly.js b/silly.js index 7d854a7..397de0f 100644 --- a/silly.js +++ b/silly.js @@ -8,13 +8,13 @@ let inputRange = 4; let shift = 4; let base = 2 ** (bits - shift); -let reduction = 0; +let reduction = 4; 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 = 1; +let epsilonBits = 1 ; let epsilon = 2 ** epsilonBits; function toFixed(float) { @@ -145,7 +145,7 @@ deltaCount = 0; console.log('done'); -console.log(`size of enloggen table: ${entries * 2} entries, ${bytes} bytes`); +console.log(`size of enloggen table: ${entries} entries, ${bytes} bytes`); console.log(`size of empower table: ${entries * 2} entries, ${bytes * 2} bytes`); let m = 0; From c3c5968749a7b74f0365018869cd33e97c3dabd6 Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Sat, 7 Jan 2023 20:32:59 -0800 Subject: [PATCH 10/10] experimenting with fixed-point log lookup table probably won't be enough precision to work with at a size that fits in memory :D --- silly.js => fixed.js | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename silly.js => fixed.js (100%) diff --git a/silly.js b/fixed.js similarity index 100% rename from silly.js rename to fixed.js