Python Strings: Medical Insurance Project - Float Question

In this exercise the hint shows me that my output should be:

Average BMI: 25.83

but I get:

Average BMI: 25.830000000000002

my code is here:

total_bmi = 0

for bmi in bmis:
  total_bmi += float(bmi)

average_bmi = total_bmi/len(bmis)
print("Average BMI: " + str(average_bmi))

I don’t see that I’m omitting any code included in the hints. Can anyone shed some light on why this is happening?

You have to adjust the precision of the float you want printed. The main reason it’s happening is because computers work in binary while we use a decimal system. Just like there are rational numbers that are hard to represent in decimal, there are rational numbers that are hard to represent in binary.

An easy example in decimal is 1/3, which is 0.333… but it’s observable that if you multiply it by 3 you will get a number that is easily represented in decimals: 1.

A more involved example:
Go to a binary/decimal calculator and convert 0.379 from decimal to binary, depending on how many bits of precision you ask for, you’ll get something around 0.0110000100000110001, now if you convert this binary number back to decimal you get… drumroll… 0.3789997100830078125.

N.B: The numbers in question are specifically rational (instead of irrational, which are part of the real numbers). The key difference is that rational numbers are still technically a discrete object because it can be represented by a ratio of two integers (whether they are represented that way by all computers is a different issue). The nature of the representation of real numbers is a bit more involved and is tangential (and I don’t have the ability to concicely describe it neatly).

From earlier: 0.333… may be hard to express in decimal but it is always part of some integer whole, by definition. Whereas irrational numbers (pi, sqrt(2), e, etc) cannot be represented as a ratio of integers. So real numbers are the first set of numbers where there’s a concrete issue in digital representation because of their continuous nature… a compromise cannot be avoided in this instance.

A perhaps interesting side-note, if you want to mitigate the loss of precision, you can explore using a rational data type… I think python has a fractions library. I know haskell and c++ do as well. Link for more info: Rational data type - Wikipedia. This might be overkill, but it helps me sleep at night hahahaha.

Python example:

>>> from fractions import Fraction
>>> Fraction(3,7)
Fraction(3, 7)
>>> x = Fraction(3,7)
>>> x * 7
Fraction(3, 1) # 21/7 = 3/1
2 Likes

you can also use the Python round function to have it look better:
round( number, 2) would round number to 2 decimal places for example.
For an output that goes to 4 decimal places (or less) you could use:

print("Average BMI: " + str( round(average_bmi, 4)) )

1 Like

This topic was automatically closed 41 days after the last reply. New replies are no longer allowed.