大数无法正确解析以太币。

7

我有以下内容:

import { BigNumber } from "@ethersproject/bignumber";
import { parseUnits } from "@ethersproject/units";

const decimals = 18;

export const add = (a: string, b: string): string => {
  const _a = parseUnits(a, decimals);
  console.log(_a.toString(), a);
  const _b = BigNumber.from(b);
  const res = _a.add(_b).toString();
  return res;
};

// a = 123456789123456789.123456789123456789
// b = 1
// _a.toString() = 123456789123456789123456789123456789
// res = 123456789123456789123456789123456790

我有没有忽略一些显而易见的原因,导致res不能被计算为"123456789123456790.123456789123456789"呢?

即使我不传递decimals参数,结果仍然相同。(理想情况下,我不想指定实际的小数位数)

1个回答

15

BigNumber实际上是一个BigInteger(其中不能包含小数值)。这是因为在以太坊区块链上,数字被表示为256位整数。您还可以查看我在同一主题下的答案

现在处理十进制数可能会让人感到困惑,让我这样解释:

// creating BigNumber instances
const a = ethers.BigNumber.from('1') // creates BigNumber of 1
const b = ethers.utils.parseUnits('1', 18) // Creates BigNumber of 1000000000000000000
const c = ethers.utils.parseEther('1') // same as above, by default 18 decimals

a.toString() // '1'
b.toString() // '1000000000000000000'
ethers.utils.formatEther(a) // '0.000000000000000001'
ethers.utils.formatEther(b) // '1.0'

如果你主要处理带小数的货币数字,那么你可以简单地使用parseEtherformatEther这两个工具函数。

如果你不是在处理货币,而只是一个BigNumber类型的数字,那么你可以使用BigNumber.from()value.toString()


5
为什么如果我们不使用货币,就不能使用BigNumber.from()呢?例如,如果我尝试ethers.BigNumber.from("21.33"),它会失败。我还没有弄清楚为什么。 - BigRon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接