Decimal class in Python


Series Overview

This article is part of the series. Below are links to all posts in the series:
  1. Floating-Point Arithmetic
  2. Decimal class in Python
  3. Fraction class in Python
  4. Rounding Errors in Java

What's inside this article ⌄
  • How to use Python Decimal class
  • Fix floating point precision errors Python
  • Decimal vs float Python comparison
  • How to handle money calculations Python
  • Tolerance-based comparisons

Floating Away: Slightly Unstable World of Real Number Computations. Using Decimal class in Python.


We had a discussion about the reasons behind rounding errors and floating-point arithmetic. It’s time to solve them.

In most cases, it’s acceptable to use float and double datatypes for your computations. However, there might be a few cases that require accuracy. At least, money computations.

There are special types that are intended to help you with that. In this post, we are working with Decimal class.

Let’s create the price and tax_rate variables in Python:

price: float = 19.99
tax_rate: float = 0.075

Then, some computations:

tax_amount = price * tax_rate
total_price = price + tax_amount

If you print tax_amount and total_price, you get:

1.4992499999999997
21.48925

As you see, the tax_amount value is not correct. The reason is rounding errors. We can fix that by using decimal.Decimal class:

price = Decimal("19.99")
tax_rate = Decimal("0.075")

Crucial that you should use strings to initialize Decimal! If you used constructor like this: Decimal(19.99), results won’t change.

The rest of the code remains the same. The Output this time will be:

1.49925
21.48925

Also, you should avoid direct comparison of float-point numbers:

a: float = 0.1 + 0.2
b: float = 0.3
print(a == b) # Output: false

Instead, we should use Decimal objects initialized with strings (!):

a1 = Decimal("0.1") + Decimal("0.2")
b1 = Decimal("0.3")
print(a1 == b1) # Output: true

Or tolerance-based comparisons:

a = 0.1 + 0.2
b = 0.3
epsilon = 1e-10
print(abs(a - b) < epsilon)