mandel-6502/silly.js

115 lines
2.4 KiB
JavaScript
Raw Normal View History

2023-01-08 01:20:18 +00:00
// 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
2023-01-08 01:32:38 +00:00
let reduction = 0;
2023-01-08 01:20:18 +00:00
// 12-bit lookup table
2023-01-08 01:32:38 +00:00
//let reduction = 4;
2023-01-08 01:20:18 +00:00
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
2023-01-08 01:32:38 +00:00
let deltas = 0;
let count = 0;
let deltaCount = 0;
let results = 0;
function round(n, x) {
return Math.round(x * n) / n;
}
2023-01-08 01:20:18 +00:00
while (true) {
let a = Math.trunc(Math.random() * logEntries);
let b = Math.trunc(Math.random() * logEntries);
2023-01-08 01:32:38 +00:00
let expected = a * b;
let result = mul(a, b);
2023-01-08 01:20:18 +00:00
2023-01-08 01:32:38 +00:00
let delta = Math.abs(result - expected);
2023-01-08 01:20:18 +00:00
let epsilon = 1;
if (delta >= epsilon) {
2023-01-08 01:32:38 +00:00
let percent = 100 * (delta / expected);
//console.log(`${a} * ${b} = ${expected}, but got ${result} delta ${delta} ${Math.round(percent * 100) / 100}%`);
deltas += delta;
deltaCount++;
2023-01-08 01:20:18 +00:00
} else {
2023-01-08 01:32:38 +00:00
//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;
2023-01-08 01:20:18 +00:00
}
}
console.log('done');