0

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
Yu Hao
  • 119,891
  • 44
  • 235
  • 294
David
  • 1
  • 1
  • 1
    I think the settings in `decimal` only affect numbers created with that package, not regular `float` numbers. Also, this is just an artefact from how floating point numbers are represented in memory. Is this really a problem? – tobias_k Aug 31 '17 at 14:14
  • Possible duplicate of [How can I format a decimal to always show 2 decimal places?](https://stackoverflow.com/questions/1995615/how-can-i-format-a-decimal-to-always-show-2-decimal-places) – Antonis Christofides Aug 31 '17 at 14:22
  • Thanks,; the problem is with Gurobi while reading these numbers to solve the optimization problem. This increases the time of computation which is approximated more than a day and precision, meaning reaching the optimal solution with zero gap. – David Aug 31 '17 at 14:26

2 Answers2

2

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.

Christian Dean
  • 22,138
  • 7
  • 54
  • 87
0

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)
Antonis Christofides
  • 6,990
  • 2
  • 39
  • 57