In this track: Digital value and units
Why floating-point amounts can fail
Ordinary JavaScript numbers cannot preserve every possible Wei amount.
A ruler with marks one centimetre apart cannot represent every millimetre. A numeric format also has a fixed resolution.
1 ETH = 1000000000 Gwei = 1000000000000000000 Wei.
Decimal fractions can be approximate
JavaScript Number uses binary floating-point arithmetic. Some decimal fractions cannot be represented exactly in that format. A familiar example is 0.1 + 0.2, which does not evaluate to the exact decimal value 0.3.
Large integers can lose units
Number.MAX_SAFE_INTEGER is 9007199254740991. One ETH in Wei is much larger than this. Converting a sufficiently large integer string into Number can erase the difference between neighboring Wei amounts before you perform any calculation.
Use strings and BigInt deliberately
Accept the user’s decimal input as text. Parse it into whole Wei, represented using BigInt or another exact integer library. BigInt does not directly represent fractions, so the decimal scale remains an explicit part of your conversion logic.
Check the original input
A JSON number can lose precision during parsing. For large ABI arguments, our encoder accepts quoted decimal strings and rejects unsafe numeric inputs. Once a digit has been rounded away, wrapping the rounded result in BigInt cannot recover it.
Can BigInt recover digits already lost by Number rounding?
You must preserve the original text before the lossy conversion happens.
Original explanations by EtherTools. Examples are educational and source-linked; this site is independent of the Ethereum Foundation. Our approach.