![](images/spacer.gif) | Code: TernaryI32 = (function () { "use strict";
let MAX_VALUE = 926510094425920; let MIN_VALUE = -926510094425920;
function ctor(value) { let result = new.target ? this : Object.create(ctor.prototype); if (value instanceof ctor) { result.pos = value.pos; result.neg = value.neg; } else { let pos = 0, neg = 0, rem; value = Math.trunc(value); if (!Number.isSafeInteger(value)) value = 0; for (let i = 1; i && value; i <<= 1) { rem = value % 3; rem = (rem % 2 * 3 - rem) / 2; if (rem > 0) pos += i; if (rem < 0) neg += i; value = (value - rem) / 3; } result.pos = pos; result.neg = neg; } return result; };
function abs(a) { return sign(a) < 0 ? neg(a) : ctor(a); };
function add(a, b) { let pos_A = a.pos | 0; let neg_A = a.neg | 0; let pos_B = b.pos | 0; let neg_B = b.neg | 0; let pos_XOR = pos_A ^ pos_B; let neg_XOR = neg_A ^ neg_B; let t = pos_XOR & neg_XOR; pos_XOR ^= t; neg_XOR ^= t; let pos_AND = pos_A & pos_B; let neg_AND = neg_A & neg_B; let pos_P = pos_XOR | pos_AND; let neg_P = neg_XOR | neg_AND; let pos_G = pos_XOR | neg_AND; let neg_G = neg_XOR | pos_AND; let pos_SUM = pos_G; let neg_SUM = neg_G; for (let step = 1; step <= 16; step += step) { let pos_Pr = pos_P << step; let neg_Pr = neg_P << step; let pos_Gr = pos_G << step; let neg_Gr = neg_G << step; t = pos_Gr | neg_Gr; pos_P &= pos_Pr | ~(pos_G | (neg_G & neg_Pr & ~t)); neg_P &= neg_Pr | ~(neg_G | (pos_G & pos_Pr & ~t)); t = (pos_G & pos_Pr) | (neg_G & neg_Pr); pos_G = t & pos_Gr; neg_G = t & neg_Gr; } pos_P <<= 1; neg_P <<= 1; pos_XOR = pos_P ^ pos_SUM; pos_XOR = neg_P ^ neg_SUM; t = pos_XOR & neg_XOR; pos_AND = pos_P & pos_SUM; neg_AND = neg_P & neg_SUM; let result = Object.create(ctor.prototype); result.pos = neg_AND | (pos_XOR ^ t); result.neg = pos_AND | (neg_XOR ^ t); return result; };
function addcarry(a, b, cin) { let t = addext(a, b); a = t[0]; let cout = t[1]; if (cin > 0) { b = inc(a); if (a.pos === -1) cout = Math.min(cout, 0) + 1; } else if (cin < 0) { b = dec(a); if (a.neg === -1) cout = Math.max(cout, 0) - 1; } else { b = a; } return [b, cout]; };
function addext(a, b) { let sum = add(a, b); let carry = sign(a); if (carry !== sign(b) || carry === sign(sum)) carry = 0; return [sum, carry]; };
function cast(value) { return value instanceof ctor ? value : ctor(value); };
function cldiv(a, b) { return cldiv_i(a, b)[0]; };
function cldiv_i(a, b) { let sign_B = sign(b); if (sign_B < 0) { a = neg(a); b = neg(b); } else if (!sign_B) { return null; } let exp_A = 31 - Math.clz32(a.pos | a.neg); let exp_B = 31 - Math.clz32(b.pos | b.neg); let pos_Q = 0; let neg_Q = 0; while (exp_A >= exp_B) { let i = exp_A - exp_B; if ((a.pos >> exp_A) & 1) { a = tritsub(a, shift(b, i)); pos_Q |= 1 << i; } else if ((a.neg >> exp_A) & 1) { a = tritadd(a, shift(b, i)); neg_Q |= 1 << i; } exp_A--; } if (sign_B < 0) { a = neg(a); } let q = Object.create(ctor.prototype); q.pos = pos_Q; q.neg = neg_Q; return [q, a]; };
function clmul(a, b) { if (((a.pos | a.neg) >>> 0) < ((b.pos | b.neg) >>> 0)) { let t = a; a = b; b = t; } let pos_B = b.pos | 0; let neg_B = b.neg | 0; let both_B = pos_B | neg_B; let result = ctor(0); for (let i = 0; both_B; i++) { let j = 1 << i; if (both_B & j) { both_B ^= j; result = ((pos_B & j) ? tritadd : tritsub)(result, shift(a, i)); } } return result; };
function clmulinv(a) { let sign = a.neg & 1; if (sign) { a = neg(a); } else if (!(a.pos & 1)) { return null; } let b = ctor(1); let pos_R = 0; let neg_R = 0; for (let i = 0; i < 32; i++) { if (b.pos & 1) { b = tritsub(b, a); pos_R |= 1 << i; } else if (b.neg & 1) { b = tritadd(b, a); neg_R |= 1 << i; } b = shift(b, -1); } if (sign) { let t = pos_R; pos_R = neg_R; neg_R = t; } let result = Object.create(ctor.prototype); result.pos = pos_R; result.neg = neg_R; return result; };
function clpow(a, n) { if (!(n >= 0 && n <= Number.MAX_SAFE_INTEGER)) { return null; } let s = (a.pos & 1) - (a.neg & 1); if (!s && n > 31) return ctor(0); let b = [a, clmul(a, a)]; let r = n % 3; let c = r ? b[r - 1] : ctor(1); for (let step = 3; n = (n - r) / 3, n > 0 && step < 32; step *= 3) { r = n % 3; if (r) { let d = b[r - 1]; let pos_D = d.pos | 0; let neg_D = d.neg | 0; let both_D = pos_D | neg_D; let n = 32 / step; a = ctor(0); for (let i = 0; i < n && both_D; i++) { let j = 1 << i; if (both_D & j) { both_D ^= j; a = (pos_D & j ? tritadd : tritsub)(a, shift(c, i * step)); } } c = a; } } if (s < 1 && n % 2) c = neg(c); return c; };
function clrem(a, b) { return cldiv_i(a, b)[1]; };
function clz32(a) { return Math.clz32(a.pos | a.neg); };
function cmp(a, b) { let pos_A = a.pos | 0; let neg_A = a.neg | 0; let pos_B = b.pos | 0; let neg_B = b.neg | 0; a = ((pos_A & ~pos_B) | (neg_B & ~neg_A)) >>> 0; b = ((pos_B & ~pos_A) | (neg_A & ~neg_B)) >>> 0; return Math.sign(a - b); };
function ctz32(a) { a = a.pos | a.neg; return a ? 31 - Math.clz32(a & -a) : 32; };
function dec(a) { return neg(inc(neg(a))); };
function div(a, b) { let t = divrem_i(a, b); return t && ctor(t[0]); };
function divrem_i(a, b) { b = valueOf(b); if (!b) return null; a = valueOf(a); let r = a % b; return [(a - r) / b, r]; };
function inc(a) { let pos_A = a.pos | 0; let neg_A = a.neg | 0; let b = pos_A + 1; let c = b & -b; let result = Object.create(ctor.prototype); result.pos = b & ~(neg_A & c); result.neg = (neg_A & ~c) | (c - 1); return result; };
function max(a, b) { return ctor(cmp(a, b) < 0 ? a : b); };
function min(a, b) { return ctor(cmp(a, b) > 0 ? a : b); };
function mul(a, b) { let pos_A = a.pos | 0; let neg_A = a.neg | 0; let pos_B = b.pos | 0; let neg_B = b.neg | 0; let hi_A = valueOf({pos: pos_A >>> 16, neg: neg_A >>> 16}); let lo_A = valueOf({pos: pos_A & 0xFFFF, neg: neg_A & 0xFFFF}); let hi_B = valueOf({pos: pos_B >>> 16, neg: neg_B >>> 16}); let lo_B = valueOf({pos: pos_B & 0xFFFF, neg: neg_B & 0xFFFF}); return ctor((hi_A * lo_B + hi_B * lo_A) % 43046721 * 43046721 + lo_A * lo_B); };
function mulext(a, b) { let pos_A = a.pos | 0; let neg_A = a.neg | 0; let pos_B = b.pos | 0; let neg_B = b.neg | 0; let hi_A = valueOf({pos: pos_A >>> 16, neg: neg_A >>> 16}); let lo_A = valueOf({pos: pos_A & 0xFFFF, neg: neg_A & 0xFFFF}); let hi_B = valueOf({pos: pos_B >>> 16, neg: neg_B >>> 16}); let lo_B = valueOf({pos: pos_B & 0xFFFF, neg: neg_B & 0xFFFF}); let hi_C = hi_A * hi_B; let mi_C = hi_A * lo_B + hi_B * lo_A; let lo_C = lo_A * lo_B; let r = mi_C % 43046721; lo_C += r * 43046721; hi_C += (mi_C - r) / 43046721; if (lo_C > MAX_VALUE) { lo_C -= 1853020188851841; hi_C ++; } else if (lo_C < MIN_VALUE) { lo_C += 1853020188851841; hi_C --; } return [ctor(lo_C), ctor(hi_C)]; };
function mulinv(a) { a = valueOf(a); if (!(a % 3)) return null; let x = a % 43046721; let y = (1 - x * x) % 43046721; while (y) { x = x * (1 + y) % 43046721; y = y * y % 43046721; } let lo = a % 43046721; let hi = (a - lo) / 43046721; return ctor(x + ((1 - lo * x) / 43046721 - hi * x % 43046721) * x % 43046721 * 43046721); }
function nabs(a) { return neg(abs(a)); };
function nadd(a, b) { return neg(add(a, b)); };
function neg(a) { let result = Object.create(ctor.prototype); result.pos = a.neg; result.neg = a.pos; return result; };
function nmax(a, b) { return neg(max(a, b)); };
function nmin(a, b) { return neg(min(a, b)); };
function nmul(a, b) { return neg(mul(a, b)); };
function parity(a) { a = a.neg | a.pos; a ^= a >> 16; a ^= a >> 8; a ^= a >> 4; return (0x6996 >> (a & 15)) & 1; };
function pow(a, n) { if (!(n >= 0 && n <= Number.MAX_SAFE_INTEGER)) { return null; } let result = ctor(1); while (n >= 1) { if (n % 2 >= 1) { result = mul(result, a); } a = mul(a, a); n /= 2; } return result; };
function rem(a, b) { let t = divrem_i(a, b); return t && ctor(t[1]); };
function shift(a, n) { let pos, neg; if (n < -31 || n > 31) { pos = neg = 0; } else if (n < 0) { pos = a.pos >>> (-n); neg = a.neg >>> (-n); } else { pos = a.pos << n; neg = a.neg << n; } let result = Object.create(ctor.prototype); result.pos = pos; result.neg = neg; return result; };
function sign(a) { return Math.sign((a.pos >>> 0) - (a.neg >>> 0)); };
function sub(a, b) { return add(a, neg(b)); };
function tritabs(a) { let result = Object.create(ctor.prototype); result.pos = a.pos | a.neg; result.neg = 0; return result; };
function tritadd(a, b) { let pos_A = a.pos | 0; let neg_A = a.neg | 0; let pos_B = b.pos | 0; let neg_B = b.neg | 0; let pos_XOR = pos_A ^ pos_B; let neg_XOR = neg_A ^ neg_B; let t = pos_XOR & neg_XOR; let pos_AND = pos_A & pos_B; let neg_AND = neg_A & neg_B; let result = Object.create(ctor.prototype); result.pos = neg_AND | (pos_XOR ^ t); result.neg = pos_AND | (neg_XOR ^ t); return result; };
function tritany(a, b) { let pos_OR = a.pos | b.pos; let neg_OR = a.neg | b.neg; let t = pos_OR & neg_OR; let result = Object.create(ctor.prototype); result.pos = pos_OR ^ t; result.neg = neg_OR ^ t; return result; };
function tritcmp(a, b) { return tritany(a, neg(b)); };
function tritcons(a, b) { let result = Object.create(ctor.prototype); result.pos = a.pos & b.pos; result.neg = a.neg & b.neg; return result; };
function tritdec(a) { return neg(tritinc(neg(a))); };
function triteq(a, b) { let neg = (a.pos ^ b.pos) | (a.neg ^ b.neg); let result = Object.create(ctor.prototype); result.pos = ~neg; result.neg = neg; return result; };
function tritgt(a, b) { return tritlt(b, a); };
function tritgte(a, b) { return neg(tritlt(a, b)); };
function tritinc(a) { let pos_A = a.pos | 0; let neg_A = a.neg | 0; let result = Object.create(ctor.prototype); result.pos = ~(pos_A | neg_A); result.neg = pos_A; return result; };
function tritlt(a, b) { let pos = (~a.pos & b.pos) | (a.neg & ~b.neg); let result = Object.create(ctor.prototype); result.pos = pos; result.neg = ~pos; return result; };
function tritlte(a, b) { return neg(tritlt(b, a)); };
function tritmax(a, b) { let result = Object.create(ctor.prototype); result.pos = a.pos | b.pos; result.neg = a.neg & b.neg; return result; };
function tritmin(a, b) { let result = Object.create(ctor.prototype); result.pos = a.pos & b.pos; result.neg = a.neg | b.neg; return result; };
function tritmul(a, b) { let pos_A = a.pos | 0; let neg_A = a.neg | 0; let pos_B = a.pos | 0; let neg_B = a.neg | 0; let result = Object.create(ctor.prototype); result.pos = (pos_A & pos_B) | (neg_A & neg_B); result.neg = (pos_A & neg_B) | (neg_A & pos_B); return result; };
function tritnabs(a) { return neg(tritabs(a)); };
function tritnadd(a, b) { return neg(tritadd(a, b)); };
function tritneg(a) { return tritpos(neg(a)); }; function tritneq(a, b) { return neg(tritneq(a, b)); };
function tritnmax(a, b) { return neg(tritmax(a, b)); };
function tritnmin(a, b) { return neg(tritmin(a, b)); };
function tritnmul(a, b) { return neg(tritmul(a, b)); };
function tritnneg(a) { return neg(tritneg(a)); };
function tritnpos(a) { return neg(tritpos(a)); };
function tritnzero(a) { return neg(tritzero(a)); };
function tritpos(a) { a = a.pos; let result = Object.create(ctor.prototype); result.pos = a; result.neg = ~a; return result; };
function tritsub(a, b) { return tritadd(a, neg(b)); };
function tritzero(a) { a = a.pos | a.neg; let result = Object.create(ctor.prototype); result.pos = ~a; result.neg = a; return result; };
function toBalanced(a, tab) { let pos_A = a.pos; let neg_A = a.neg; let result = ""; for (let i = 1 << 31; i; i >>>= 1) { result += tab[(pos_A & i) ? 2 : +!(neg_A & i)]; } return result; };
function valueOf(a) { let pos = a.pos | 0; let neg = a.neg | 0; let result = 0; for (let i = 1; pos || neg; i *= 3) { result += i * ((pos & 1) - (neg & 1)); pos >>>= 1; neg >>>= 1; } return result; };
ctor.MAX_VALUE = Object.freeze(ctor(MAX_VALUE)); ctor.MIN_VALUE = Object.freeze(ctor(MIN_VALUE)); ctor.ZERO = Object.freeze(ctor(0)); ctor.abs = function(a, b) { return abs(cast(a)); }; ctor.add = function(a, b) { return add(cast(a), cast(b)); }; ctor.addcarry = function(a, b, c) { return addcarry(cast(a), cast(b), +c); }; ctor.addext = function(a, b) { return addext(cast(a), cast(b)); }; ctor.cast = cast; ctor.cldiv = function(a, b) { return cldiv(cast(a), cast(b)); }; ctor.clmul = function(a, b) { return clmul(cast(a), cast(b)); }; ctor.clmulinv = function(a) { return clmulinv(cast(a)); }; ctor.clpow = function(a, b) { return clpow(cast(a), Math.trunc(b)); }; ctor.clrem = function(a, b) { return clrem(cast(a), cast(b)); }; ctor.clz32 = function(a) { return clz32(cast(a)); }; ctor.cmp = function(a, b) { return cmp(cast(a), cast(b)); }; ctor.ctz32 = function(a) { return ctz32(cast(a)); }; ctor.dec = function(a, b) { return dec(cast(a)); }; ctor.div = function(a, b) { return div(cast(a), cast(b)); }; ctor.eq = function(a, b) { return !cmp(cast(a), cast(b)); }; ctor.gt = function(a, b) { return cmp(cast(a), cast(b)) > 0; }; ctor.gte = function(a, b) { return cmp(cast(a), cast(b)) >= 0; }; ctor.inc = function(a, b) { return inc(cast(a)); }; ctor.iseven = function(a) { return !parity(cast(a)); }; ctor.isneg = function(a) { return sign(cast(a)) < 0; }; ctor.isodd = function(a) { return !!parity(cast(a)); }; ctor.ispos = function(a) { return sign(cast(a)) > 0; }; ctor.iszero = function(a) { return !sign(cast(a)); }; ctor.lt = function(a, b) { return cmp(cast(a), cast(b)) < 0; }; ctor.lte = function(a, b) { return cmp(cast(a), cast(b)) <= 0; }; ctor.max = function(a) { return max(cast(a), cast(b)); }; ctor.min = function(a) { return min(cast(a), cast(b)); }; ctor.mul = function(a, b) { return mul(cast(a), cast(b)); }; ctor.mulext = function(a, b) { return mulext(cast(a), cast(b)); }; ctor.mulinv = function(a) { return mulinv(cast(a)); }; ctor.nabs = function(a) { return nabs(cast(a)); }; ctor.nadd = function(a, b) { return nadd(cast(a), cast(b)); }; ctor.neg = function(a) { return neg(cast(a)); }; ctor.neq = function(a, b) { return !!cmp(cast(a), cast(b)); }; ctor.nmax = function(a, b) { return nmax(cast(a, b)); }; ctor.nmin = function(a, b) { return nmin(cast(a, b)); }; ctor.nmul = function(a, b) { return nmul(cast(a, b)); }; ctor.pow = function(a, b) { return pow(cast(a), Math.trunc(b)); }; ctor.rem = function(a, b) { return rem(cast(a), cast(b)); }; ctor.shift = function(a, n) { return shift(cast(a), Math.trunc(n)); }; ctor.sign = function(a) { return sign(cast(a)); }; ctor.sub = function(a, b) { return sub(cast(a), cast(b)); }; ctor.tritabs = function(a) { return tritabs(cast(a)); }; ctor.tritadd = function(a, b) { return tritadd(cast(a), cast(b)); }; ctor.tritany = function(a, b) { return tritany(cast(a), cast(b)); }; ctor.tritcmp = function(a, b) { return tritcmp(cast(a), cast(b)); }; ctor.tritcons = function(a, b) { return tritcons(cast(a), cast(b)); }; ctor.tritdec = function(a) { return tritdec(cast(a)); }; ctor.triteq = function(a, b) { return triteq(cast(a), cast(b)); }; ctor.tritgt = function(a, b) { return tritgt(cast(a), cast(b)); }; ctor.tritgte = function(a, b) { return tritgte(cast(a), cast(b)); }; ctor.tritinc = function(a) { return tritinc(cast(a)); }; ctor.tritlt = function(a, b) { return tritlt(cast(a), cast(b)); }; ctor.tritlte = function(a, b) { return tritlte(cast(a), cast(b)); }; ctor.tritmax = function(a, b) { return tritmax(cast(a), cast(b)); }; ctor.tritmin = function(a, b) { return tritmin(cast(a), cast(b)); }; ctor.tritmul = function(a, b) { return tritmul(cast(a), cast(b)); }; ctor.tritnabs = function(a, b) { return tritnabs(cast(a), cast(b)); }; ctor.tritnadd = function(a, b) { return tritnadd(cast(a), cast(b)); }; ctor.tritneg = function(a) { return tritneg(cast(a)); }; ctor.tritneq = function(a, b) { return tritneq(cast(a), cast(b)); }; ctor.tritnmax = function(a, b) { return tritnmax(cast(a), cast(b)); }; ctor.tritnmin = function(a, b) { return tritnmin(cast(a), cast(b)); }; ctor.tritnmul = function(a, b) { return tritnmul(cast(a), cast(b)); }; ctor.tritnneg = function(a) { return tritnneg(cast(a)); }; ctor.tritnpos = function(a) { return tritnpos(cast(a)); }; ctor.tritnzero = function(a) { return tritnzero(cast(a)); }; ctor.tritpos = function(a) { return tritpos(cast(a)); }; ctor.tritsub = function(a, b) { return tritsub(cast(a), cast(b)); }; ctor.tritzero = function(a) { return tritzero(cast(a)); }; ctor.prototype.toBalanced = function(tab) { return toBalanced(this, String(tab == null ? "T01" : tab).split("")); }; ctor.prototype.toString = function(radix) { return valueOf(this).toString(radix); }; ctor.prototype.valueOf = function() { return valueOf(this); };
return ctor; })(); | ![](images/spacer.gif) |