3

So I started building a function with which I aim to correct the first 3 'allocations' which exceed a certain limit.

Below function now returns a list with the exceeded values per value in the passed list.

def correct_wrong_allocations_zw(weight_vect):
    temp_weight_vect = list(weight_vect[:3])

    limits = [1.00, 0.30, 0.25]
    too_much_list = []

    too_much = 0.00
    for i in range(0, len(temp_weight_vect)):
        if temp_weight_vect[i] > limits[i]:
            too_much_list.append(temp_weight_vect[i]-limits[i])

    return too_much_list

allocations = [0.10, 0.40, 0.50, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00]
allocations = correct_wrong_allocations_zw(allocations)
print allocations

The difference between allocations[1] and limits[1] is 0.10, yet the result of this program is:

[0.10000000000000003, 0.25]

What is going on?

Rory Daulton
  • 21,934
  • 6
  • 42
  • 50
Lazykiddy
  • 1,525
  • 1
  • 11
  • 18
  • Use a formatted printf to round the value. The internal binary representation used cannot exactly match the rational 1/10, any more than a printed decimal can exactly match the rational 1/3. – mpez0 May 12 '16 at 12:00
  • Look into the [decimal](https://docs.python.org/2.7/library/decimal.html) module if you want to control floating point precision beyond formatted output. – user2390182 May 12 '16 at 12:04
  • 1
    I wish people would stop linking to that general purpose question and find something more Python specific, because there are nuances for how this works or can be fixed for each language. – Mark Ransom May 12 '16 at 13:44

1 Answers1

2

This, Floating Point Arithmetic: Issues and Limitations, might be helpful.

Note that this is in the very nature of binary floating-point: this is not a bug in Python, and it is not a bug in your code either. You’ll see the same kind of thing in all languages that support your hardware’s floating-point arithmetic (although some languages may not display the difference by default, or in all output modes).


BTW, you can use the module decimal to see the exact value stored in any particular Python float. In your case,

>>> from decimal import Decimal
>>> Decimal(0.4-0.3)
Decimal('0.100000000000000033306690738754696212708950042724609375')
SparkAndShine
  • 17,001
  • 22
  • 90
  • 134