Reputation: 23098
I have used "decimal" constants, just in case. Could I rather use integers for the same purpose safely, like integer 0 and 1 here? Its for storing money.
if SOMETHING:
invoice.tax_rate = Decimal(TAXRATE_STRING)
else:
invoice.tax_rate = Decimal("0.00")
invoice.total_amount =\
invoice.pretax_amount * (Decimal("1") + invoice.tax_rate)
Upvotes: 0
Views: 144
Reputation: 1123360
Yes, you can safely use integers; they'll be coerced to Decimal
objects as required.
The Decimal
class implements many of the numeric emulation hooks to do so, including the __r*__
variants to ensure that this works even if the integer is the left-hand operand.
For your specific case, if the tax rate was set to integer 0
and you used an integer 1
, you'd get:
>>> from decimal import Decimal
>>> Decimal('20.00') * (1 + 0)
Decimal('20.00')
The summing of the tax rate results in a Decimal
object if it is not set to integer 0
:
>>> 1 + Decimal('0.20')
Decimal('1.20')
etc.
Internally, the decimal._convert_other()
function is used to handle the coercion. It'll convert integers and long integers to Decimal()
always, floats only when explicitly instructed to (only for rich comparisons, so ==
and <=
, etc.), the rest is explicitly rejected. Floats are not suited for automatic conversion; it is too easy to introduce bugs in your code if you allowed for floats to be converted implicitly.
Upvotes: 1
Reputation: 500663
Yes you can, for example:
In [8]: d = decimal.Decimal("123.45")
In [9]: d / 10
Out[9]: Decimal('12.345')
Note that this does not work with floating-point values:
In [10]: d / 123.45
TypeError: unsupported operand type(s) for /: 'Decimal' and 'float'
I would argue that this is good news, because implicitly mixing Decimal
and float
would be too error-prone.
Upvotes: 1