Python. Numbers with fixed precision. Class Decimal

Numbers with fixed precision. Class Decimal


 1. Features of using numbers with fixed precision. Class Decimal

Fixed-precision numbers are Decimal-type numbers that use a fixed number of decimal places when calculating. The Decimal type is a specially designed class (since Python 2.4).

 The term “fixed precision” means that with the help of such numbers you can save a value that will always have a certain number of decimal places.

For example, you need to store numbers strictly with the number 6 decimal places.

The Decimal class is implemented in the decimal module. To use the capabilities of the Decimal class, you need to run the command

from decimal import Decimal


2. How to set the desired fixed precision using the Decimal class? Examples

To create an object of the Decimal class, the constructor of this class is used. The constructor receives a string with a number in which the specified precision is indicated, for example

Decimal('0.002') # fixed precision with 3 decimal places
Decimal('0.23') # fixed precision with 3 decimal places
Decimal('0.00001') # fixed precision with 3 decimal places


3. An example of the need to use the Decimal class in Python programs

The example demonstrates the need to write programs using the Decimal class for cases where the precision of the calculation is extremely important.

# Numbers with fixed precision.
# include the Decimal class from the decimal module
from decimal import Decimal

# normal calculation, there is an error
a = 0.2+0.2+0.2-0.4 # a =   0.20000000000000007 - error (???)
print('a = ', a)

# calculation using the class Decimal
b = Decimal('0.2')+Decimal('0.2')+Decimal('0.2')-Decimal('0.4')
print('b = ', b) # b = 0.2 - accurate result

The result of the program

a = 0.20000000000000007
b = 0.2

First, an object (variable) is created with the name a, into which the sum is written


Then the value of this variable is displayed. As can be seen from the result, the result of computing the variable a contains an error. This is due to the fact that the memory allocated for numbers of the real type is limited. In other words, the number of bits in the representation of real numbers is insufficient.

In the next step, an object with the name b is created, into which the sum is written using the Decimal class

b = Decimal('0.2')+Decimal('0.2')+Decimal('0.2')-Decimal('0.4')

After displaying the value of b on the screen, it can be seen that the value of the variable b is represented exactly without error.


4. An example of using the Decimal class and str() function

In the previous example, the constructor of the Decimal class received a string with a number


wherein the determined precision (decimal 1) and the value of 0.2.

A situation is possible when you need to pass directly a number and not a string. In this case, it is convenient to use the str() function, as shown below

# calculation using the Decimal class
b = Decimal(str(0.2))+Decimal(str(0.2))+Decimal(str(0.2))-Decimal(str(0.4))
print('b = ', b) # b = 0.2

The str() function takes a number and translates it into a string

x = str(0.2) # x = '0.2'


5. Using fixed precision for numbers with different precision representations. Example

It is possible that in an expression containing the Decimal class there are numbers with different precision of representations. In this case, the precision of the result is automatically set equal to the precision of the number with the greatest precision of the presentation.

For example. When adding three numbers

c = Decimal('0.1')+Decimal('0.001')+Decimal(str(0.01)) # c = 0.111

the precision of 3 decimal places is automatically set, since the constructor

Decimal ('0.001')

determines the number 0.001 with the greatest precision of representation.


6. Creating objects of the Decimal class from real numbers. Example

For cases when a real number is available, it is possible to create an object of the Decimal class. In this case, the from_float() method of the Decimal class is used.

# Creating an object of type Decimal does not always work
# Case 1. Distorted precision
# x1 =   2.479999999999999982236431605997495353221893310546875
x1 = Decimal.from_float(2.48)
print('x1 =',x1)

# Case 2. Fixed precision
x2 = Decimal.from_float(2.5) # x2 = 2.5 - correct precision
print('x2 =', x2)

The result of the above code

x1 = 2.479999999999999982236431605997495353221893310546875
x2 = 2.5

As can be seen from the result, it is not always possible to obtain fixed accuracy when using the from_float() method.


7. Global setting of precision. Example

There are times when precision in a program needs to be set for all operations of the current control stream. This can be, for example, a presentation of monetary amounts taking into account cents (2 decimal places).


# Global setting of precision
# include the Decimal class
from decimal import Decimal

a = Decimal(5)/Decimal(13) # precision is not defined
print('a = ', a) # a =   0.3846153846153846153846153846

# precision of 6 decimal places
import decimal
b = Decimal(5)/Decimal(13)
print('b = ', b) # b = 0.384615

c = Decimal(6)/Decimal(13)
print('c = ', c) # c = 0.461538

The result of the program

a = 0.3846153846153846153846153846
b = 0.384615
c = 0.461538

In the above example, global precision for the Decimal class is set using the getcontext() function, which returns a context object in this module. The precision is set in the current control stream.


Related topics