Last active
October 20, 2018 17:56
-
-
Save Hokid/edaa3066ddcc183a342704acc3580c2e to your computer and use it in GitHub Desktop.
__math_notes
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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