I have the following:
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
Am I missing something obvious as to why res
wouldn't be calculated as "123456789123456790.123456789123456789"?
Even if I don't pass in decimals
, it's still the same result. (Ideally I wouldn't want to specify an actual decimals value)
The
BigNumber
is actually a BigInteger (you can't have decimal values in it). This is because on the Ethereum blockchain, numbers are represented as 256 bit integers. You can also see my answer to the same topic.Now working with decimals could be confusing let me put it this way:
If you're mostly dealing with currency numerics having decimals, then you can simply stick with
parseEther
andformatEther
utils.If you're not working with currency and it's still a BigNumber then you'll can use
BigNumber.from()
andvalue.toString()