Skip to content

Instantly share code, notes, and snippets.

@Hokid
Last active October 20, 2018 17:56
Show Gist options
  • Save Hokid/edaa3066ddcc183a342704acc3580c2e to your computer and use it in GitHub Desktop.
Save Hokid/edaa3066ddcc183a342704acc3580c2e to your computer and use it in GitHub Desktop.
__math_notes
// fix it
const normFract = (c) => {if(c[1] === 0n || c[2] === 0n) { c[1] = c[2] = 0n; } return c;}
const divFract = (a, b) => { let _a = a[1] * b[2], _b = a[2] * b[1]; return normFract([_a === 0n || _b === 0n ? 0n : _a / _b, _a === 0n || _b === 0n ? 0n : _a % _b, _b]) }
const gcd = (a, b) => { if (b === 0n) return a; return gcd(b, a % b); }
const toFract = (a) => [0n, a[1] + a[0] * a[2], a[2]];
const div = (a, b) => { let _a = divFract(toFract(a), toFract(b)); return [_a[0], _a[1] / (gcd(_a[1], _a[2]) || 1n), _a[2] / (gcd(_a[1], _a[2]) || 1n)]; }
div([5n, 3n, 4n], [0n, 3n, 4n]) // [7n, 2n, 3n]
// produce multiplication `a` by `b` and then divide by `c`
// without going beyond the integer maximum `MAX_INT_VALUE`
function maxint__muldiv(a, b, c, MAX_INT_VALUE) {
let fractions_sum = 0n;
let result = 0n;
if (a === 0n || b === 0n) return 0n;
0n / c; // throw 'Division by zero' error if `c` is 0
if (a > MAX_INT_VALUE) throw '`a` must be less or equal max int `MAX_INT_VALUE`';
if (b > MAX_INT_VALUE) throw '`b` must be less or equal max int `MAX_INT_VALUE`';
if (c > MAX_INT_VALUE) throw '`b` must be less or equal max int `MAX_INT_VALUE`';
const max_a = MAX_INT_VALUE / b;
if (a <= max_a) return [(result = a * b) / c, result % c];
while(a !== 0n) {
const a_part = max_a > a ? a : max_a;
const a_part_by_b_prod = a_part * b;
result += a_part_by_b_prod / c;
fractions_sum += a_part_by_b_prod % c;
a -= a_part;
}
result += fractions_sum / c;
return [result, fractions_sum % c];
}
// https://en.wikipedia.org/wiki/Adder_(electronics)
function full_adder(a, b, c) { return ( ( ( (a^b)&c ) | (a&b) ) <<1 ) | ( (a^b)^c ); }
// addiction two numbers
function add(a, b, max_pos = 0b1000) {
let pointer = 0b0001;
let carry = 0b0;
let result = 0b0;
let shift = 0;
while(pointer !== (max_pos<<1)) {
const $a = (a&pointer)>>shift;
const $b = (b&pointer)>>shift;
const $result = full_adder($a, $b, carry);
result = result|(($result&0b01)<<shift);
carry = $result>>1;
pointer = pointer<<1;
shift = shift + 1;
}
return result;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment