With a limit on decimals, rounding errors can exist.
A token with 18 decimals can potentially (and does) have rounding errors.
The EVM takes the
floor, or rounds down, to the nearest whole number.
Knowing this ahead of time, developers can do math calculations appropriately and accurately.
// assuming the usage of `new BN()` - pseudocode below
To convert 1 token to 18 decimals: (1.mul(1e18)) = 1000000000000000000
To convert 1 token to 15 decimals: (1.mul(1e15)) = 1000000000000000
To convert 12345 (assuming smallest unit) to decimal representation (15): (12345.div(1e15)) = 0.000000000012345
floor of my result and trust that's how the EVM will handle the calculation.
Token decimals: 15
User A Balance: 3.5 tokens
Actual balance as represented by uint256: 3500000000000000 <- this is the number I use