如何划分两个原生 JavaScript BigInt 并获得小数结果
How to divide two native JavaScript BigInt's and get a decimal result
以下是我目前尝试过的方法。我想要 12.34
:
BigInt('12340000000000000000') / BigInt('1000000000000000000')
12n
Number(BigInt('12340000000000000000') / BigInt('1000000000000000000'))
12
FWIW,当我使用 JSBI 库时,它按照我想要的方式工作:
JSBI.BigInt('12340000000000000000') / JSBI.BigInt('1000000000000000000');
12.34
这不是原生的吗?
你应该乘以分子以容纳你需要的位数,执行除法,然后用正常的浮点除法除法。
(运行 在支持 BigInt 的浏览器中,如 Chrome)
var a = 12340000000000000000n;
var b = 1000000000000000000n;
console.log(Number(a * 100n / b) / 100);
仅在“末尾”转换为数字,您将损失最少的精度。
更精确
如果你需要超过 16 位的精度 和 需要小数,那么你需要自己实现一种 BigDecimal
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() {
const s = this.bigint.toString().padStart(BigDecimal.decimals+1, "0");
return s.slice(0, -BigDecimal.decimals) + "." + s.slice(-BigDecimal.decimals)
.replace(/\.?0+$/, "");
}
}
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());
同样,这需要一个支持 BigInt
(撰写本文时 Chrome)的浏览器。
以下是我目前尝试过的方法。我想要 12.34
:
BigInt('12340000000000000000') / BigInt('1000000000000000000')
12n
Number(BigInt('12340000000000000000') / BigInt('1000000000000000000'))
12
FWIW,当我使用 JSBI 库时,它按照我想要的方式工作:
JSBI.BigInt('12340000000000000000') / JSBI.BigInt('1000000000000000000');
12.34
这不是原生的吗?
你应该乘以分子以容纳你需要的位数,执行除法,然后用正常的浮点除法除法。
(运行 在支持 BigInt 的浏览器中,如 Chrome)
var a = 12340000000000000000n;
var b = 1000000000000000000n;
console.log(Number(a * 100n / b) / 100);
仅在“末尾”转换为数字,您将损失最少的精度。
更精确
如果你需要超过 16 位的精度 和 需要小数,那么你需要自己实现一种 BigDecimal
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() {
const s = this.bigint.toString().padStart(BigDecimal.decimals+1, "0");
return s.slice(0, -BigDecimal.decimals) + "." + s.slice(-BigDecimal.decimals)
.replace(/\.?0+$/, "");
}
}
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());
同样,这需要一个支持 BigInt
(撰写本文时 Chrome)的浏览器。