Reputation: 30857
While the problem in this particular instance deals with Django and Python, I imagine this problem has shown up elsewhere as well.
Float values have a precision problem, and when used for currency can sometimes lead to inaccuracies, so fixed-precision Decimal is the storage type of choice in most instances.
But what about the case where a price is combined with non-integer quantity, such as in an invoice or receipt. Say Fairy Dust costs $19.99 per gram, and a customer buys 3.5 grams of the stuff. The price is Decimal, while the quantity is a float.
The total then is Decimal(19.99) * float(3.5)
. But multiplying floats and Decimals isn't allowed:
>>> from decimal import *
>>> Decimal(19.99) * float(3.5)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for *: 'Decimal' and 'float'
Of course, we could cast the price to a float first, but then we lose any advantage we otherwise would have gained by storing the value as a decimal. Or we could store the quantity as a decimal, but that would mean arbitrarily picking a range and precision for the quantity. But at design time, the developer wouldn't necessarily know what range/precision would be necessary for the quantity (which is why floating point numbers exist). Is there a better way?
I'm sure this problem has been solved before; what is the optimal way to go about this type of calculation?
Upvotes: 1
Views: 1829