This commit is contained in:
Brooke Vibber 2023-01-07 17:52:14 -08:00
parent d32b630320
commit a6c49a2ef9

View file

@ -4,19 +4,22 @@
let logBits = 8; let logBits = 8;
let logEntries = 2 ** logBits; let logEntries = 2 ** logBits;
let powBits = 16; let powBits = 19;
let powEntries = (2 ** powBits); let powEntries = 2 ** powBits;
// Room to hold powers up to 4 // Room to hold powers up to 4
let shift = 4; let shift = 3;
let base = 2 ** (powBits - shift); let base = 2 ** (powBits - shift);
// 16-bit lookup table // 16-bit lookup table
let reduction = 0; let reduction = 7;
// 12-bit lookup table // 12-bit lookup table
//let reduction = 4; //let reduction = 4;
let powCount = powEntries >> reduction;
function toFixed(float) { function toFixed(float) {
return Math.round(float * base); return Math.round(float * base);
} }
@ -26,7 +29,7 @@ function toFloat(fixed) {
} }
// 256x2 = 512 bytes // 256x2 = 512 bytes
let enloggen = new Uint16Array(logEntries); let enloggen = new Uint32Array(logEntries);
for (let i = 0; i < logEntries; i++) { for (let i = 0; i < logEntries; i++) {
enloggen[i] = toFixed(Math.log2(i)); enloggen[i] = toFixed(Math.log2(i));
} }
@ -35,7 +38,6 @@ for (let i = 0; i < logEntries; i++) {
// 64kx2 = 128 KiB // 64kx2 = 128 KiB
// can reduce number by reducing precision // can reduce number by reducing precision
// or splitting into high & low vals // or splitting into high & low vals
let powCount = powEntries >> reduction;
let empower = new Uint16Array(powCount); let empower = new Uint16Array(powCount);
for (let i = 0; i < powCount; i++) { for (let i = 0; i < powCount; i++) {
let fixed = i << reduction; let fixed = i << reduction;
@ -43,12 +45,12 @@ for (let i = 0; i < powCount; i++) {
} }
// returns fixed // returns fixed point
function log2(byte) { function log2(val) {
return enloggen[byte]; return enloggen[val];
} }
// returns 16-bit number // returns rounded integer
function pow2(fixed) { function pow2(fixed) {
n = (fixed >> reduction); n = (fixed >> reduction);
return empower[n]; return empower[n];
@ -62,17 +64,16 @@ function mul(a, b) {
return pow2(la + lb); return pow2(la + lb);
} }
/*
for (let i = 0; i < logEntries; i++) { for (let i = 0; i < logEntries; i++) {
let l = log2(i); let l = log2(i);
let p = pow2(l); let p = pow2(l);
console.log(`${i} ${l} ${p}`) //console.log(`${i} ${l} ${p}`)
if (i !== 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); //process.exit(1);
*/
// now just try multipling numbers // now just try multipling numbers
let deltas = 0; let deltas = 0;
@ -84,9 +85,15 @@ function round(n, x) {
return Math.round(x * n) / n; return Math.round(x * n) / n;
} }
/*
while (true) { while (true) {
let a = Math.trunc(Math.random() * logEntries); let a = Math.trunc(Math.random() * logEntries);
let b = 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 expected = a * b;
let result = mul(a, b); let result = mul(a, b);
@ -102,13 +109,22 @@ while (true) {
//console.log(`${a} * ${b} = ${result}`); //console.log(`${a} * ${b} = ${result}`);
} }
count++; 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('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}`);