UNPKG

functionalscript

Version:

FunctionalScript is a purely functional subset of JavaScript

66 lines (65 loc) 1.78 kB
import { abs, sign } from "../bigint/module.f.js"; const twoPow53 = 9007199254740992n; const twoPow54 = 18014398509481984n; const increaseMantissa = ([m, e]) => (min) => { if (m === 0n) { return [m, e]; } const s = sign(m); m = abs(m); while (true) { if (m >= min) { return [BigInt(s) * m, e]; } m = m << 1n; e--; } }; const decreaseMantissa = ([m, e]) => (max) => { if (m === 0n) { return [m, e]; } const s = sign(m); m = abs(m); while (true) { if (m < max) { return [BigInt(s) * m, e]; } m = m >> 1n; e++; } }; const pow = (base) => (exp) => base ** BigInt(exp); const pow5 = pow(5n); export const multiply = ([m, e]) => (mul) => [m * mul, e]; const divide = ([m, e]) => (div) => [[m / div, e], m % div]; const round53 = ([[m, e], r]) => { const mabs = abs(m); const s = BigInt(sign(m)); const [m54, e54] = decreaseMantissa([mabs, e])(twoPow54); const o54 = m54 & 1n; const m53 = m54 >> 1n; const e53 = e54 + 1; if (o54 === 1n && r === 0n && mabs === m54 >> BigInt(e - e54)) { const odd = m53 & 1n; return multiply([m53 + odd, e53])(s); } return multiply([m53 + o54, e53])(s); }; export const decToBin = (dec) => { if (dec[0] === 0n) { return [0n, 0]; } if (dec[1] >= 0) { const bin = [dec[0] * pow5(dec[1]), dec[1]]; const inc = increaseMantissa(bin)(twoPow53); return round53([inc, 0n]); } const p = pow5(-dec[1]); const [m, e] = increaseMantissa(dec)(p * twoPow53); const mAbs = abs(m); const s = BigInt(sign(m)); const qr = divide([mAbs, e])(p); const r53 = round53(qr); return multiply(r53)(s); };