"use strict";
/**
 * These implementations mirror the Bitcoin Script based implementations used.
 * They are necessary to ensure that we produce the same results as the oracles.
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.exp = exports.log10 = exports.log = exports.log2 = exports.e = exports.scale = exports.precision = void 0;
exports.precision = 16;
exports.scale = 2 ** exports.precision;
const scale2 = 2 ** 20;
const ln2 = Math.round((Math.log(10) * scale2) / Math.log2(10));
const ln10 = Math.round((Math.log10(10) * scale2) / Math.log2(10));
exports.e = Math.round(Math.E * exports.scale);
/**
 * Works for numbers between 100 and 0.001
 */
function log2(x) {
    if (x > 6553600 || x < 66) {
        throw new Error(); // loops arent sufficient;
    }
    let b = 32768;
    let y = 0;
    // If less than 1
    for (let i = 0; i < 10; i++) {
        if (x < exports.scale) {
            x = x * 2;
            y = y - exports.scale;
        }
    }
    // If more than 1
    for (let i = 0; i < 10; i++) {
        if (x >= 2 * exports.scale) {
            x = Math.floor(x / 2);
            y = y + exports.scale;
        }
    }
    let z = x;
    // loop precision times
    for (let i = 0; i < 16; i++) {
        z = Math.floor((z * z) / exports.scale);
        if (z >= 2 * exports.scale) {
            z = Math.floor(z / 2);
            y = y + b;
        }
        b = Math.floor(b / 2);
    }
    return y;
}
exports.log2 = log2;
function log(x) {
    return Math.floor((log2(x) * ln2) / scale2);
}
exports.log = log;
function log10(x) {
    return Math.floor((log2(x) * ln10) / scale2);
}
exports.log10 = log10;
/**
 * Adapted from https://github.com/PetteriAimonen/libfixmath/blob/master/libfixmath/fix16_exp.c
 */
function exp(x) {
    if (x >= 681391 || x < 0)
        throw new Error();
    if (x == 0)
        return exports.scale;
    if (x == 65536)
        return exports.e;
    let result = x + exports.scale;
    let term = x;
    for (let i = 2; i < 30; i++) {
        term = Math.floor(Math.floor(term * x) / Math.floor(i * exports.scale));
        result += term;
        if (term < 500 && (i > 15 || term < 20))
            break;
    }
    return result;
}
exports.exp = exp;
//# sourceMappingURL=fixMathOld.js.map