0

I'm writing a program that calculates the expected value of the sum of two discrete random variables. Here is the code:

EX = 0
EY = 0

X_number=int(input("Enter the number of possible values for X: "))
print("Enter ", X_number, " values of X and their probabilities. Press enter after each pair: ")
for i in range(X_number):
    value, prob = input().split()
    EX += float(value)*float(prob)

Y_number = int(input("\nEnter the number of possible values for Y: "))
print("Enter", Y_number, "values of Y and their probabilities. Press enter after each pair: ")
for i in range(Y_number):
    value, prob = input().split()
    EY += float(value)*float(prob)
print("\nE(X) = ", EX)
print("E(Y) = ", EY)
print("E(X+Y) = ", EX+EY)

The program works fine, but sometimes I see strange small inaccuracies in the numbers, which miraculously disappear in later results during the same run, e.g for data:

 Enter the number of possible values for X: 3
Enter  3  values of X and their probabilities. Press enter after each pair: 
9 0.3
3 0.5
-7 0.2

Enter the number of possible values for Y: 2
Enter 2 values of Y and their probabilities. Press enter after each pair: 
100 0.9
-50 0.1

I get

E(X) =  2.799999999999999
E(Y) =  85.0
E(X+Y) =  87.8

I've read that this is due to the binary exponential storing of float in the computer, but such inaccuracies when dealing with numbers with only one decimal place aren't good, either :( Also, I have been using double in C++ a lot on numbers with 3-4 decimal places and everything was always accurate, so I'm disappointed by Python here. Please tell me how to fix this. The program is simple, so I prefer not to use numpy and other advanced stuff. Maybe a switch to fixed-point will do, as I only need 4-5 decimal places?

Kola_163
  • 23
  • 7
  • 3
    Instead of floats, use [`decimal.Decimal`](https://docs.python.org/3.7/library/decimal.html). – Klaus D. Jul 30 '19 at 19:40
  • Is your complaint that you got `2.799999999999999` but want `2.8`? The difference is 10^-15, which is miniscule. That value should be accurate enough for reasonable work. If you just want it printed with fewer digits, then do you need to know how to control the formatting of floating-point numbers for printing or display in Python? – Eric Postpischil Jul 30 '19 at 19:41
  • also: [How to avoid floating point errors?](https://stackoverflow.com/questions/19473770/how-to-avoid-floating-point-errors) – wwii Jul 30 '19 at 19:42
  • 1
    There would be no difference between C++ and Python here. – juanpa.arrivillaga Jul 30 '19 at 20:09
  • @juanpa.arrivillaga: Quite clearly there is a difference between C++ and Python here, as the OP gets different results with C++ and Python. The difference is in the formatting of floating-point numbers for display. Instead of incorrectly marking these questions as duplicates of [Is floating point math broken?](https://stackoverflow.com/questions/588004/is-floating-point-math-broken), the formatting behaviors and the differences between the languages should be explained (whether by answering or by marking as a duplicate of a correct original). – Eric Postpischil Jul 31 '19 at 12:09
  • 1
    @EricPostpischil I didn't vote to close, but I'll go ahead and re-open it. My point was that both Python and C++ would be using similar (likely the exact same) underlying representation for a `double` in C++ and a `float` object in Python. I believe you are right, that the difference the OP is seeing is dependent on how the output is being formatted, but that is only speculation without more details. for example, does the op actually care about maintaining accuracy, or just something "good enough" that they aren't bothered by the stranger results. – juanpa.arrivillaga Jul 31 '19 at 18:29
  • Thanks @KlausD. :-) Decimal worked for me, but I wonder what's the difference in storing that fixed this? The whole computer is base 2 not 10 after all... Or is it just fixed-point with precision 28? – Kola_163 Jul 31 '19 at 21:48

0 Answers0