如何除以两个原生 JavaScript BigInt 并获得小数结果

问题描述 投票:0回答:1

这是我到目前为止所尝试过的。我正在寻找一个

12.34
:

BigInt('12340000000000000000') / BigInt('1000000000000000000')

12n

Number(BigInt('12340000000000000000') / BigInt('1000000000000000000'))

12

FWIW,当我使用 JSBI 库时,它按照我想要的方式工作:

JSBI.BigInt('12340000000000000000') / JSBI.BigInt('1000000000000000000');

12.34

这本身就不可能吗?

javascript biginteger bigint
1个回答
42
投票

您应该乘以分子以适应所需的位数,执行除法,然后用普通浮点除法除法。

var a = 12340000000000000000n;
var b =  1000000000000000000n;

console.log(Number(a * 100n / b) / 100);

仅在“末尾”从 BigInt 转换为 Number,您将损失最小的精度。

更精准

如果您需要超过 16 位的精度 并且需要小数,那么您需要抛出自己的一种

BigDecimal
API 实现,或使用现有的 API。

这是一个使用

BigInt
作为其基本类型的简单方法,并结合了一个配置,该配置确定每个此类 BigInt 的多少位(从右侧)应解释为小数(小数部分中的数字)。例如,最后一个信息将用于在将数字输出为字符串时插入小数分隔符。

class BigDecimal {
    constructor(value) {
        let [ints, decis] = String(value).split(".").concat("");
        decis = decis.padEnd(BigDecimal.decimals, "0");
        this.bigint = BigInt(ints + decis);
    }
    static fromBigInt(bigint) {
        return Object.assign(Object.create(BigDecimal.prototype), { bigint });
    }
    divide(divisor) { // You would need to provide methods for other operations
        return BigDecimal.fromBigInt(this.bigint * BigInt("1" + "0".repeat(BigDecimal.decimals)) / divisor.bigint);
    }
    toString() {
        let s = this.bigint.toString().replace("-", "").padStart(BigDecimal.decimals+1, "0");
        s = (s.slice(0, -BigDecimal.decimals) + "." + s.slice(-BigDecimal.decimals))
               .replace(/(\.0*|0+)$/, "");
        return this.bigint < 0 ? "-" + s : s;                
    }
}
BigDecimal.decimals = 18; // Configuration of the number of decimals you want to have.

// Demo
var a = new BigDecimal("123456789123456789876");
var b = new BigDecimal( "10000000000000000000");

console.log(a.divide(b).toString());

附录:在后来的问答中我用加法、减法、乘法和舍入功能丰富了这个课程。

© www.soinside.com 2019 - 2024. All rights reserved.