How to perform accurate Decimal Calculations using Python?


In this article, we will learn how to perform Accurate Decimal Calculations in Python.

Methods Used

  • Using the Decimal() function of the decimal Module

  • Using the fsum() function of the math module

The inability of floating-point numbers to accurately represent all base-10 numbers is a well-known drawback. Furthermore, even straightforward mathematical computations have few errors. For instance −

Example

The following program shows the inability of floating-point integers to express all base-10 numbers accurately −

x = 4.2
y = 3.1
 
# printing the sum of both the variables
print("x + y =", x + y)
 
# checking if the sum is both the variables is equal to 7.3
print((x + y) == 7.3)

Output

On executing, the above program will generate the following output −

x + y = 7.300000000000001
False

These errors are a "feature" of the CPU that underlies the system and the IEEE 754 arithmetic standard that is used by its floating-point unit. There is nothing you can do to prevent such mistakes if you write your code using float instances because Python's float data type saves data using the native representation.

Using the decimal module will give you greater accuracy at the cost of some performance. Let us see it below.

Method 1: Using Decimal() function of the decimal Module

Example

The following program shows the use of the Decimal() function to perform accurate decimal calculations −

# importing Decimal from decimal module
from decimal import Decimal
x = Decimal('4.2')
y = Decimal('3.1')
# printing the sum of both the variables
print("x + y =", x + y)
# checking if the sum is both the variables is equal to 7.3 using by passing the sum to the Decimal Function
print((x + y) == Decimal('7.3'))

Output

On executing, the above program will generate the following output −

x + y = 7.3
True

In the above code, it could appear a little strange at first i.e., specifying numbers as strings. Nevertheless, decimal objects work exactly as you would want them to (supporting all common math operations, etc.). They appear like regular numbers when you print them or utilize them in string formatting functions.

The ability to control several aspects of calculations, such as the number of digits and rounding, is a key feature of decimal.

Example

To perform this, create a local context and modify its settings.

# importing localcontext from decimal module
from decimal import localcontext
x = Decimal('2.3')
y = Decimal('2.7')
# dividing x by y(returns as a floating-point number)
print(x / y)
with localcontext() as context:
   # rounding the number upto 3 digits i.e, precision 3
   context.prec = 3
   # Dividing x by y with precision set to 3
   print(x / y)

Output

On executing, the above program will generate the following output −

0.8518518518518518518518518519
0.852

Incrementing the precision value to ‘60’ for higher accuracy

Example

# importing localcontext from decimal module
import decimal
from decimal import localcontext
x = decimal.Decimal('2.3')
y = decimal.Decimal('2.7')
# dividing x by y(returns as a floating-point number)
print(x / y)
with localcontext() as context:
   # Rounding the number upto 60 digits i.e, precision 60
   context.prec = 60
   # Dividing x by y with precision set to 3
   print(x / y)

Output

On executing, the above program will generate the following output −

0.8518518518518518518518518519
0.851851851851851851851851851851851851851851851851851851851852

Method 2: Using the fsum() function of the math module

The decimal module implements the "General Decimal Arithmetic Specification" of IBM.

It goes without saying that there are a good amount of customizing choices that go beyond this article.

Python beginners might be tempted to utilize the decimal module to get around float data type's reported accuracy issues. It's important to know your application domain, too. It's simply more typical to utilize the normal floating-point type when working with science or engineering problems, computer graphics, or most other things of a scientific nature.

For example, relatively few elements in the actual world are measured with the accuracy of 17 digits offered by floats. Therefore, even minute calculational errors have no impact. The speed of native floats is also noticeably faster, which is crucial if you need to run a lot of calculations.

Example

However, you can't fully avoid the errors. Numerous algorithms have been studied extensively by mathematicians, and some are better than others at handling errors. Additionally, consequences resulting from practices like subtractive cancellation and adding large and small numbers require some care.

inputList = [1.23e+18, 1, -1.23e+18]

# observe how the 1 disappears here if we perform sum() on the list
print(sum(inputList)) 

Output

On execution, the above program will generate the following output −

0.0

fsum() finds the sum between a given range or an iterable. It needs the import of the math library. Its widely used in mathematical calculations.

Syntax

Below is the syntax of the function.

maths.fsum( iterable )

The iterable can be a range, array, or list.

Return Type −

It returns a floating point number.

Example

The following example can be used to address a more accurate implementation in math.fsum()

# importing math module 
import math
# input list
inputList = [1.23e+18, 1, -1.23e+18]
# adding the sum of elements of the list using the fsum() function
print(math.fsum(inputList))

Output

On executing, the above program will generate the following output −

1.0

In contrast, you actually need to research and understand the error propagation properties of other algorithms.

Despite all of this, programs that deal with subjects like finance are where the decimal module is most frequently used. It is incredibly unpleasant when tiny inaccuracies appear in such systems' calculations.

The decimal module thus offers a means of avoiding that. When Python interfaces with databases, Decimal objects are frequently encountered again, especially when accessing financial data.

Conclusion

We learned in this article how normal calculations fail in particular instances and why we require correct decimal calculations. We learned how to perform accurate decimal calculations with two separate functions: decimal() and fsum(). We also learned how to use the localcontext() function to set the precision of the result.

Updated on: 27-Jan-2023

963 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements