如何用ethers.js的BigNumber正确计算含小数的乘法(如100000*1.004)?
解决ethers.js BigNumber计算100000*1.004的正确方式
你的问题出在两次使用parseUnits转换后相乘,导致数值被重复放大了1e18倍:
parseUnits("100000", 18)是把100000转成100000 * 1e18的整数形式parseUnits("1.004", 18)是把1.004转成1.004 * 1e18的整数形式- 两者相乘后得到
100000*1.004*1e36,再用formatUnits转回去时只除以了1e18,最终结果自然是正确值的1e18倍。
正确计算方式有三种:
方式1:相乘后除以1e18精度单位
const ethers = require("ethers"); // 转换两个数值为18位精度的BigNumber const num = ethers.parseUnits("100000", 18); const multiplier = ethers.parseUnits("1.004", 18); // 相乘后除以1e18的基准单位(即parseUnits("1", 18)) const result = num.mul(multiplier).div(ethers.parseUnits("1", 18)); // 转换回人类可读数值 console.log(ethers.formatUnits(result, 18)); // 输出:100400.0
方式2:仅转换小数,整数直接用BigNumber.from
const ethers = require("ethers"); // 整数直接用BigNumber.from创建,避免额外放大 const num = ethers.BigNumber.from(100000); // 小数转成18位精度的BigNumber const multiplier = ethers.parseUnits("1.004", 18); // 相乘后除以1e18基准单位 const result = num.mul(multiplier).div(ethers.parseUnits("1", 18)); console.log(ethers.formatUnits(result, 18)); // 输出:100400.0
方式3:用整数运算直接规避小数
既然1.004等价于1004/1000,直接用整数乘法和除法计算,完全不需要精度转换:
const ethers = require("ethers"); const result = ethers.BigNumber.from(100000).mul(1004).div(1000); console.log(result.toString()); // 直接输出:100400
内容的提问来源于stack exchange,提问作者Mickey
相关产品推荐
相关产品推荐

