1

I am using BigNumber from etherjs and I am doing this very simple operation:

const cost = BigNumber.from(3)
    .div(BigNumber.from(1000))
    .mul(BigNumber.from(3));

  console.log(cost.toString());

It outputs '0', but should be 0.09.

Why? What am I doing wrong?

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
Stefdelec
  • 2,711
  • 3
  • 33
  • 40
  • Side note: Do you know that JavaScript has a native big integer type now, [`BigInt`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt)? Supported in nearly all environments (not IE11, but even Microsoft doesn't support IE anymore). You could work in units that are a multiple of the precision you need. For instance, if you need two digits of precision to the right of the decimal point, you'd work with values that are 100 times the size. Then divide for output. – T.J. Crowder May 01 '21 at 07:30
  • FWIW you could just do `BigNumber.from(3).div(1000).mul(3)` – Madbreaks Dec 13 '22 at 23:21

1 Answers1

6

As far as I can tell from the documentation, Ethers' BigNumber only handles big integers. Nothing in the documentation mentions fractional values or precision or scale, all of which you'd expect to see in a library handling fractional values. Separately, the documentation mentions it currently uses BN.js in its implementation of BigNumber. BN.js doesn't handle fractional values. From its documentation:

Note: decimals are not supported in this library.

That's not terribly clear (most of the examples are in decimal), they probably meant fractional values aren't supported.

A couple of options for you:

  1. You could work in units that are a multiple of the precision you need. For instance, if you need two digits of precision to the right of the decimal point, you'd work with values that are multiplied by 100. Then divide by 100 to get the whole portion for output, and do a remainder operation on 100 to get the fractional portion for output (formatting with a leading 0 if needed).

  2. There are several libraries for big numbers that handle fractional values, such as bignumber and big.js.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875