Often for quantities that require precise calculations, a FloatField
[Django-doc] is used. This is not a good idea since decimal numbers often can not be precisely converted to a float
, so it will result in rounding errors. These errors will further propagate when one performs calculations.
Why is it a problem?
A float
uses the IEEE-754 standard [wiki] to represent floating point numbers. While this is a good standard and actually aims to make calculations very precise, it can result in rounding errors for decimal numbers. Quantities like currencies make use of the decimal number system, and often do not allow much rounding errors.
What can be done to resolve the problem?
One can make use of a DecimalField
[Django-doc]. DecimalField
s are represented at the Django/Python layer as a Decimal
, and at the database often use a dedicated decimal type. These represent numbers as decimal numbers, and thus make, for decimal numbers, correct sums, etc.
from django.db import models
class Product(models.Model):
price = models.DecimalField(max_digits=12, decimal_places=2)
The Django documentation has a section on FloatField
vs. DecimalField
which compares both types.
Extra tips
There are Django packages that make it more convenient to work with money. For example django-money
[GitHub] and django-moneyfield
[GitHub].
These represent money with two fields, a DecimalField
for the value, and an extra column that denotes the currency. This is often more convenient and provides extra functionalities like converting money from one currency to another.