Search code examples
javascriptdecimalcurrency

Get the least significant digit as scalar to add or substract with (from a decimal.js object)


i am working with money values here. I have an unknown amount of money of a unkown currency (compiletime unknown ofc). I have multiple targets to divide that amout to.

One example:

Amount is $3.02 and i will divide with three friends so each will get $1 leaving 2 cents to spare. Now as the amount has to be correct at the end i split up the remainder between the parties untill all cents to spare are gone.

Note that the same has to work for yapanese yen. They don't have cents. There it would be for example 32 divided by 3 equals 10 each and 2 to spare.

In the following code cents is a decimal.js value with the remainder of the split mentioned above (e.g "0.02" or just "2").

for (let i = 0; !cents.isZero(); i++) {
    const transactionData = transactionsData[i]
    const newAmountCents = new decimal.Decimal(transactionData.amount).plus(new decimal.Decimal("0.01"))
    console.log(`New Amount: ${newAmountCents}`)
    transactionData.amount = newAmountCents.toString()
    newCents = newCents.minus(new decimal.Decimal("0.01"))
}

As you can probably see my problem. I am adding "0.01" here and subtracting the same. But as i mentioned this is variable accoring to the decimal places of the underlying currency. How can i extract the correct "unit" and replace the "0.01" with the correct amount?


Solution

  • Yo can go this way and create sort of parse function, which will get currency value and number of shares and returns reminder and lowest possible currency value

    const parseCoin = (coin, shares) => {
      // How mutch zeros after . to use
      // Parse coin value as string and
      // find it out:
      // 3.00 -> 2
      // 3 -> 0
      let match = String(coin).match(/\.(.*)/);
      const decimalFixed = match ? match[1].length : 0;
    
      // Modulus
      let remainder = (Number(coin) % shares).toFixed(decimalFixed);
    
      // Find smallest available value
      const smallestValue = 1 / 10 ** decimalFixed;
      
      // Return object
      return { remainder, smallestValue };
    }
    
    // Test
    console.log(parseCoin(3.02, 3));
    console.log(parseCoin(32, 3));
    console.log(parseCoin(2, 2));
    console.log(parseCoin(4, 3));
    console.log(parseCoin('3.000', 3));