2 This module implements rational numbers.
4 The entry point of this module is the function
5 rat(numerator, denominator)
6 If either numerator or denominator is of an integral or rational type,
7 the result is a rational number, else, the result is the simplest of
8 the types float and complex which can hold numerator/denominator.
9 If denominator is omitted, it defaults to 1.
10 Rational numbers can be used in calculations with any other numeric
11 type. The result of the calculation will be rational if possible.
13 There is also a test function with calling sequence
15 The documentation string of the test function contains the expected
19 # Contributed by Sjoerd Mullender
24 '''Calculate the Greatest Common Divisor.'''
29 def rat(num
, den
= 1):
30 # must check complex before float
31 if isinstance(num
, complex) or isinstance(den
, complex):
32 # numerator or denominator is complex: return a complex
33 return complex(num
) / complex(den
)
34 if isinstance(num
, float) or isinstance(den
, float):
35 # numerator or denominator is float: return a float
36 return float(num
) / float(den
)
37 # otherwise return a rational
41 '''This class implements rational numbers.'''
43 def __init__(self
, num
, den
= 1):
45 raise ZeroDivisionError, 'rat(x, 0)'
49 # must check complex before float
50 if (isinstance(num
, complex) or
51 isinstance(den
, complex)):
52 # numerator or denominator is complex:
53 # normalized form has denominator == 1+0j
54 self
.__num
= complex(num
) / complex(den
)
55 self
.__den
= complex(1)
57 if isinstance(num
, float) or isinstance(den
, float):
58 # numerator or denominator is float:
59 # normalized form has denominator == 1.0
60 self
.__num
= float(num
) / float(den
)
63 if (isinstance(num
, self
.__class
__) or
64 isinstance(den
, self
.__class
__)):
65 # numerator or denominator is rational
67 if not isinstance(new
, self
.__class
__):
69 if isinstance(new
, complex):
70 self
.__den
= complex(1)
74 self
.__num
= new
.__num
75 self
.__den
= new
.__den
77 # make sure numerator and denominator don't
79 # this also makes sure that denominator > 0
83 # try making numerator and denominator of IntType if they fit
85 numi
= int(self
.__num
)
86 deni
= int(self
.__den
)
87 except (OverflowError, TypeError):
90 if self
.__num
== numi
and self
.__den
== deni
:
95 return 'Rat(%s,%s)' % (self
.__num
, self
.__den
)
99 return str(self
.__num
)
101 return '(%s/%s)' % (str(self
.__num
), str(self
.__den
))
106 return rat(a
.__num
* b
.__den
+ b
.__num
* a
.__den
,
108 except OverflowError:
109 return rat(long(a
.__num
) * long(b
.__den
) +
110 long(b
.__num
) * long(a
.__den
),
111 long(a
.__den
) * long(b
.__den
))
119 return rat(a
.__num
* b
.__den
- b
.__num
* a
.__den
,
121 except OverflowError:
122 return rat(long(a
.__num
) * long(b
.__den
) -
123 long(b
.__num
) * long(a
.__den
),
124 long(a
.__den
) * long(b
.__den
))
132 return rat(a
.__num
* b
.__num
, a
.__den
* b
.__den
)
133 except OverflowError:
134 return rat(long(a
.__num
) * long(b
.__num
),
135 long(a
.__den
) * long(b
.__den
))
143 return rat(a
.__num
* b
.__den
, a
.__den
* b
.__num
)
144 except OverflowError:
145 return rat(long(a
.__num
) * long(b
.__den
),
146 long(a
.__den
) * long(b
.__num
))
156 except OverflowError:
166 if isinstance(a
.__num
, complex):
170 if isinstance(b
.__num
, complex):
176 return rat(a
.__num
** b
.__num
, a
.__den
** b
.__num
)
177 except OverflowError:
178 return rat(long(a
.__num
) ** b
.__num
,
179 long(a
.__den
) ** b
.__num
)
187 return rat(-a
.__num
, a
.__den
)
188 except OverflowError:
189 # a.__num == sys.maxint
190 return rat(-long(a
.__num
), a
.__den
)
194 return rat(abs(a
.__num
), a
.__den
)
198 return int(a
.__num
/ a
.__den
)
202 return long(a
.__num
) / long(a
.__den
)
206 return float(a
.__num
) / float(a
.__den
)
210 return complex(a
.__num
) / complex(a
.__den
)
223 return cmp(Rat(a
), b
)
230 def __coerce__(a
, b
):
235 Test function for rat module.
237 The expected output is (module some differences in floating
242 [Rat(1,2), Rat(-3,10), Rat(1,25), Rat(1,4)]
243 [Rat(-3,10), Rat(1,25), Rat(1,4), Rat(1,2)]
249 2 1.5 (3/2) (1.5+1.5j) (15707963/5000000)
253 3.5 0.5 3.0 1.33333333333 2.82842712475 1
254 (7/2) (1/2) 3 (4/3) 2.82842712475 1
255 (3.5+1.5j) (0.5-1.5j) (3+3j) (0.666666666667-0.666666666667j) (1.43248815986+2.43884761145j) 1
258 3.5 -0.5 3.0 0.75 2.25 -1
259 3.0 0.0 2.25 1.0 1.83711730709 0
260 3.0 0.0 2.25 1.0 1.83711730709 1
261 (3+1.5j) -1.5j (2.25+2.25j) (0.5-0.5j) (1.50768393746+1.04970907623j) -1
264 (7/2) (-1/2) 3 (3/4) (9/4) -1
265 3.0 0.0 2.25 1.0 1.83711730709 -1
266 3 0 (9/4) 1 1.83711730709 0
267 (3+1.5j) -1.5j (2.25+2.25j) (0.5-0.5j) (1.50768393746+1.04970907623j) -1
268 (1.5+1.5j) (1.5+1.5j)
270 (3.5+1.5j) (-0.5+1.5j) (3+3j) (0.75+0.75j) 4.5j -1
271 (3+1.5j) 1.5j (2.25+2.25j) (1+1j) (1.18235814075+2.85446505899j) 1
272 (3+1.5j) 1.5j (2.25+2.25j) (1+1j) (1.18235814075+2.85446505899j) 1
273 (3+3j) 0j 4.5j (1+0j) (-0.638110484918+0.705394566962j) 0
278 print int(a
), long(a
), float(a
), complex(a
)
280 l
= [a
+b
, a
-b
, a
*b
, a
/b
]
290 raise SystemError, 'should have been ZeroDivisionError'
291 except ZeroDivisionError:
293 print rat(2), rat(1.5), rat(3, 2), rat(1.5+1.5j
), rat(31415926,10000000)
294 list = [2, 1.5, rat(3,2), 1.5+1.5j
]
297 if not isinstance(i
, complex):
298 print int(i
), float(i
),
302 print i
+ j
, i
- j
, i
* j
, i
/ j
, i
** j
,
303 if not (isinstance(i
, complex) or
304 isinstance(j
, complex)):
309 if __name__
== '__main__':