# Go deh!

Mainly Tech projects on Python and Electronic Design Automation.

## Tuesday, September 23, 2008

### Python Fractions issue.

There
seems to be a problem/difference in calculating with the new fractions
module when comparing Python 26rc2 and 30rc1

I was
reading the paper " href="http://conference.scipy.org/proceedings/SciPy2008/paper_3/full_text.pdf">Interval
Arithmetic: Python Implementation and Applications" and
thought to try the first example function f(x,y), which needs more
precision than Python floating point provides (on my Windows PC), to
calculate a sensible answer.

Ahah, I thought, lets
try this with Fractions - so I first installed Python 30rc1, typed in
the Function - saw the rubbish result, then used Fractions and got the
'right' result.
I then wondered if fractions had been
back-ported to Python 2.6rc2, found that it had, but got different
results.

As you can see from the table, Python
2.6rc2 has a problem calculating t3 = F(11,2) * y**8 + x/(2*y), where F
is Fraction.

I wonder where the problem
lies?

style="text-align: left; margin-left: auto; margin-right: auto; font-family: monospace;"
border="4" cellpadding="2" cellspacing="2"> style="white-space: nowrap; text-align: left; vertical-align: top;">Python
3.0rc1 (r30rc1:66507, Sep 18 2008, 14:47:08) [MSC v.1500 32 bit (Intel)]
on
win32
Type "help", "copyright", "credits" or "license" for
more information.
>>> from fractions
import Fraction as F
>>>
def f(x,y):
...     return
(
...
(333.75 - x**2)* y**6 + x**2 *
...
(11* x**2 * y**2 - 121 * y**4 - 2)
...
+ 5.5 * y**8 + x/(2*y))
...
>>>
f(77617.0, 33096.0)
1.1726039400531787
>>>
def f2(x,y):
...
return (
...
(333 + F(3,4) - x**2)* y**6 + x**2 *
...
(11* x**2 * y**2 - 121 * y**4 - 2)
...
+ F(11,2) * y**8 + x/(2*y))
...
>>>
f2(77617.0, 33096.0)
1.1726039400531787
>>>
f2(77617, 33096)
-0.82739605994682131
>>>
x,y = 77617, 33096
>>> t1 = (333 + F(3,4)
- x**2)* y**6 + x**2
>>> t1
Fraction(-7917110903377385049079188231255750815,
1)
>>> t2 = (11* x**2 * y**2 - 121 * y**4
- 2)
>>> t2
-72586759091903445314
>>>
t3 = F(11,2) * y**8 + x/(2*y)
>>> t3
7.9171113406689609e+36
>>> style="white-space: nowrap; text-align: left; vertical-align: top; width: 50%;">Python
2.6rc2 (r26rc2:66507, Sep 18 2008, 14:27:33) [MSC v.1500 32 bit
(Intel)] on win32
Type "copyright", "credits" or "license()"
for more information.
IDLE
2.6rc2
>>>
from fractions import Fraction as F
>>>
def f(x,y):
return (

(333.75 - x**2)* y**6 + x**2 *

(11* x**2 * y**2 - 121 * y**4 - 2)

+ 5.5 * y**8 + x/(2*y))

>>>
f(77617.0, 33096.0)
1.1726039400531787
>>>
def f2(x,y):
return (

(333 + F(3,4) - x**2)* y**6 + x**2 *

(11* x**2 * y**2 - 121 * y**4 - 2)

+ F(11,2) * y**8 + x/(2*y))

>>>
f2(77617.0, 33096.0)
1.1726039400531787
>>>
f2(77617, 33096)
style="background-color: rgb(255, 102, 102); font-weight: bold;">Fraction(-1,
1)
>>> x,y = 77617, 33096
>>>
t1 = (333 + F(3,4) - x**2)* y**6 + x**2
>>>
t1
Fraction(-7917110903377385049079188231255750815, 1)
>>>
t2 = (11* x**2 * y**2 - 121 * y**4 - 2)
>>>
t2
-72586759091903445314L
>>> t3
= F(11,2) * y**8 + x/(2*y)
>>> t3
style="background-color: rgb(255, 102, 102); font-weight: bold;">Fraction(7917111340668961361101134701524942849,
1)
>>>

#### 3 comments:

1. I suspect the problem is, as often with Python 2.x, the integer division (``1/2 == 0``), which has changed to ``1/2 == 0.5`` in Python 3.

Try writing the last factor in f2 as ``x/(2.0*y)``. If the result's still incorrect, please file a bug at http://bugs.python.org/.

2. Thanks Georg, that was it.

If I add a line
from __future__ import division
to the 2.6 code and re-define f2, all is well.

3. This comment has been removed by a blog administrator.