-1

I know that Decimal or a custom class is generally is the preferred way of representing currency, but I am asking if it can be also achieved using integer. If not possible, I would like to know why.

I know we should never use float to represent currency, because of the floating point precision issues:

burger = 1.3
amount = 3
total = burger * amount # 3.9000000000000004

Python have the Decimal module that solves the issue:

from decimal import Decimal

burger = Decimal('1.3')
amount = 3
total = burger * amount # Decimal('3.9')
print(total) # 3.9

But there is also the option to store the values and do the Math operations using integers. If we need to show the value to a human, we just divide by 100 to show the representation as currency:

burger = 130
amount = 3
total = burger * amount # 390
print(total / 100) # 3.9

Using integers seem much simpler, but would the integer solution work in any situation involving currency representation? Is there any trade-offs when using integer to represent currency?

Eduardo Matsuoka
  • 566
  • 6
  • 18
  • 2
    Just as you shouldn't use `float` for currency, you shouldn't use floating-point arithmetic on currency. `dollars, cents = divmod(total, 100); print(f'{dollar}.{cents:02}')`. – chepner Feb 06 '23 at 20:09
  • 2
    Not enough that personal preference would likely override them. – Scott Hunter Feb 06 '23 at 20:11
  • 1
    `Decimal` is not a cure-all: `Decimal(1) / 3 * 3 != Decimal(1)`. – chepner Feb 06 '23 at 20:14
  • @chepner careful, the `divmod` solution doesn't work so great with negative numbers. – kindall Feb 06 '23 at 20:15
  • Please note that some currencies have 3 decimal places. You need to take this into account to divide by 100 or 1000 and store the correct value. – fela Feb 06 '23 at 20:21
  • @kindall True, it's not quite as simple as I made it look. `divmod` uses floored division, when you really need something that uses towards-zero division, so that `tzDivMod(-390, 100) == (-3, -90)` (since `-3 * 100 + -90 == -390`). – chepner Feb 06 '23 at 20:23
  • I kinda favor good ol' string manipulation to format the number in that case unless you need the parts as numbers. `print((x := str(total))[:-2], ".", x[-2:], sep="")` – kindall Feb 06 '23 at 20:31
  • @PM77-1 it does not address my question, as I am asking about the difference between integer and Decimal object to represent currency. The question you pointed does not address the differences between these two and why one should use one over the another. – Eduardo Matsuoka Feb 06 '23 at 22:38

1 Answers1

-1

trade-offs between using integer or Decimal

With addition/subtraction, it makes little difference.

Consider interest/tax calculations, equated monthly installment, future value etc.
Do you want to use integers to calculate them?

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
  • You can use integers to represent Japanese currency. Their smallest unit of currency is 1 yen and a dollar used to be valued at around 100 yen. I am sure that they do these kinds of calculations there, that is why I am asking about the possibility of using integers. – Eduardo Matsuoka Feb 06 '23 at 22:33
  • 1
    Eduardo Matsuoka, it is not only about _representation_, but also of calculation. Integer math is insufficient for non-trivial money calculations. You asked for trade-offs and that is one. Further, the lowest unit in currency is not necessary the units required with banking laws. Those financial rules are overwhelming written with base-10 math in mind. – chux - Reinstate Monica Feb 06 '23 at 22:48