yhilpisch/py4fi2nd

Ch_02: there's no explicit solution in the book for the issue of Floating Point Arithmetic

Closed this issue · 1 comments

this book is good and comprehensive for people who want to enter the word of Python for finance but when I read the ch2 for the issue Floating-Point Arithmetic, I don't find the explicit way to address it in the book (yes, the author mentions Decimal module but he does not provide the corresponding fix to the example he describes before) - I don't know if the author intends to want the readers to search for the answer on their own.

so I posted in StackOverflow to look for the answer and those are Q/A

Questions

1. First Example

Expecting:

In[1]: a = 0.35 + 0.1
In[2]: print(a)
0.45

Actual:

In[1]: a = 0.35 + 0.1
In[2]: print(a)
0.44999999999999996

My take to present:

format(a, '.2f')
'0.45'

I thought Decimal could help but it looks like the same

In[1]:import decimal
      from decimal import Decimal

In[2]:Decimal(0.35) + Decimal(0.1)
Decimal('0.4499999999999999833466546306')

2. Second Example

Expecting:

In[1]:b = 0.35
In[2]:b.as_integer_ratio()
(7, 20)

Actual:

In[1]:b = 0.35
In[2]:b.as_integer_ratio()
(3152519739159347, 9007199254740992)

Answers using Decimal and fractions

You are starting with imprecise floats. Start with exact decimals, from string representation:

Decimal("0.35") + Decimal("0.1")
# => Decimal('0.45')

Decimal("0.35").as_integer_ratio()
# => (9, 20)

Or start with exact numbers (e.g. integers):

 Decimal(35) / Decimal(100)
 # => Decimal('0.35')

 from fractions import Fraction
 Fraction(35, 100)
 # => Fraction(7, 20)







The short answer is: there is no "solution" to the described "problem". This is because it is more of a feature of programming languages than a real problem. It is something that we need to live with.

Packages like Decimal allow you to deal with this aspect of floating-point numbers in that, for example, you can define yourself what kind of precision you desire.