2

I was working with a list of probabilities for an assignment, so naturally I wanted to add something to my program to make sure the list equaled '1'.

I was working with an example list [0.1, 0.2, 0.7]. Here's a small snippet of my code

list = [0.7, 0.2, 0.1]

total = 0
for i in list:
    total += i

if total != 1.0:
    print 'Bad'
else:
    print 'Good'

print total

The problem seems to stem from the order of the list? If I put in the list in the code, it tells me it doesn't equal one. However, if I switch around the values [0.1, 0.2, 0.7], suddenly it equals 1.

Can anyone explain what's going on? I'd really like it to tell me it equals '1' regardless of the order of the list.

Memo Smith
  • 69
  • 4
  • please see this -> [Super Secret document](http://stackoverflow.com/a/11950951/674039) – wim Jun 03 '15 at 03:23

4 Answers4

2

Use Python's Decimal library for accurate decimal addition, since floating point values are not very precise.

from decimal import Decimal

list = [Decimal(70)/Decimal(100), Decimal(20)/Decimal(100), Decimal(10)/Decimal(100)]

total = 0
for i in list:
    total += i

if total != 1.0:
    print('Bad')
else:
    print('Good')

print(total)

Here is your result:

Good
1.0

Henry Zhu
  • 2,488
  • 9
  • 43
  • 87
1

Whenever you are comparing floating point numbers, you have to keep a margin of delta. Because decimal numbers may not accurately represent the exact number what you want

delta = 0.000001
if (total - delta) <= 1 && (total + delta) >= 1:
    print 'Good!'
else:
    print 'Bad!'
Naman Sogani
  • 943
  • 1
  • 8
  • 28
0

This is an issue with floating point arithmetic. This guide is a good read on it and helps outline the pitfalls.

For your particular instance I would check if the result is within some tolerable distance from 1

sedavidw
  • 11,116
  • 13
  • 61
  • 95
0

It looks like you'd like to still use floating point numbers in your list and still have it come out correctly, you should use an error margin rather than a fixed number to test against:

target_value = 1.0
error_margin = 1E-10
if abs( total - target_value ) <= error_margin:
    print('Good')
else:
    print('Bad')
kponz
  • 508
  • 3
  • 7