David
David

Reputation: 1

Decimal in Python

I am using Python for programming and then Gurobi for solving my optimization problems. As a part of my codes I read the data from a text file (called “Feed2”), then do some calculations on it.

with open('Feed2.txt', 'r') as Fee:

    for i in range(C):
        Feed= Fee.readline()
        for s in L11:
            A[i,s]=float(Feed)
        for s in L12:
            A[i,s] =float(Feed)*1.28
        for s in L13:
            A[i,s] =float(Feed)*0.95

print A

The result shows some of the numbers have many digits after the decimal (such as 106.51209999999999 or 1029.4144000000001) which crates problem for Gurobi for reading all those which are not really useful digits to me. So, I want to set the number of digits after the decimal to 5 for my entire program, I followed the method explained in https://docs.python.org/3/library/decimal.html (codes are below); but nothing is changed.

from decimal import *

getcontext().prec = 5

Upvotes: 0

Views: 244

Answers (2)

Chris
Chris

Reputation: 22953

The documentation for the decimal module offers an explanation:

Unlike hardware based binary floating point, the decimal module has a user alterable precision (defaulting to 28 places) which can be as large as needed for a given problem.

When you did:

from decimal import *
getcontext().prec = 5

You only changed to precision used with Decimal objects from the decimal module. You didn't change the precision amount for Python's built-in floating point numbers.

As said in the comments, the behavior you are experiencing is not new. It's simply an side-effect of the way floating point numbers being stored in memory. If you really need the floats to stay a specific precision, use the decimal.Decimal class. e.g.:

>>> from decimal import Decimal
>>> Decimal.from_float(0.1)
Decimal('0.1000000000000000055511151231257827021181583404541015625')
>>> Decimal('0.1')
Decimal('0.1')
>>> Decimal('0.1') / Decimal('0.5')
Decimal('0.2')

If you simply need to round the decimal to a specif precision to display properly, use str.format in the format:

'{:<number of digits before decimal>.<number of digits after decimal >f}'.format(float)

Or with old style formatting:

'%<number of digits before decimal>.<number of digits after decimal >f' % (float)

Recommended reading: What Every Computer Scientist Should Know About Floating-Point Arithmetic.

Upvotes: 2

Antonis Christofides
Antonis Christofides

Reputation: 6939

If you just need to print the numbers with, for example, only two decimals:

print "%.2f" % (A,)

or the newer

print "{0:.2f}".format(A)

Upvotes: 0

Related Questions