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 type(num
) is ComplexType
or type(den
) is ComplexType
:
32 # numerator or denominator is complex: return a complex
33 return complex(num
) / complex(den
)
34 if type(num
) is FloatType
or type(den
) is FloatType
:
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 type(num
) is ComplexType
or type(den
) is ComplexType
:
51 # numerator or denominator is complex:
52 # normalized form has denominator == 1+0j
53 self
.__num
= complex(num
) / complex(den
)
54 self
.__den
= complex(1)
56 if type(num
) is FloatType
or type(den
) is FloatType
:
57 # numerator or denominator is float:
58 # normalized form has denominator == 1.0
59 self
.__num
= float(num
) / float(den
)
62 if (type(num
) is InstanceType
and
63 num
.__class
__ is self
.__class
__) or \
64 (type(den
) is InstanceType
and
65 den
.__class
__ is self
.__class
__):
66 # numerator or denominator is rational
68 if type(new
) is not InstanceType
or \
69 new
.__class
__ is not self
.__class
__:
71 if type(new
) is ComplexType
:
72 self
.__den
= complex(1)
76 self
.__num
= new
.__num
77 self
.__den
= new
.__den
79 # make sure numerator and denominator don't
81 # this also makes sure that denominator > 0
85 # try making numerator and denominator of IntType if they fit
87 numi
= int(self
.__num
)
88 deni
= int(self
.__den
)
89 except (OverflowError, TypeError):
92 if self
.__num
== numi
and self
.__den
== deni
:
97 return 'Rat(%s,%s)' % (self
.__num
, self
.__den
)
101 return str(self
.__num
)
103 return '(%s/%s)' % (str(self
.__num
), str(self
.__den
))
108 return rat(a
.__num
* b
.__den
+ b
.__num
* a
.__den
,
110 except OverflowError:
111 return rat(long(a
.__num
) * long(b
.__den
) +
112 long(b
.__num
) * long(a
.__den
),
113 long(a
.__den
) * long(b
.__den
))
121 return rat(a
.__num
* b
.__den
- b
.__num
* a
.__den
,
123 except OverflowError:
124 return rat(long(a
.__num
) * long(b
.__den
) -
125 long(b
.__num
) * long(a
.__den
),
126 long(a
.__den
) * long(b
.__den
))
134 return rat(a
.__num
* b
.__num
, a
.__den
* b
.__den
)
135 except OverflowError:
136 return rat(long(a
.__num
) * long(b
.__num
),
137 long(a
.__den
) * long(b
.__den
))
145 return rat(a
.__num
* b
.__den
, a
.__den
* b
.__num
)
146 except OverflowError:
147 return rat(long(a
.__num
) * long(b
.__den
),
148 long(a
.__den
) * long(b
.__num
))
158 except OverflowError:
168 if type(a
.__num
) is ComplexType
:
172 if type(b
.__num
) is ComplexType
:
178 return rat(a
.__num
** b
.__num
, a
.__den
** b
.__num
)
179 except OverflowError:
180 return rat(long(a
.__num
) ** b
.__num
,
181 long(a
.__den
) ** b
.__num
)
189 return rat(-a
.__num
, a
.__den
)
190 except OverflowError:
191 # a.__num == sys.maxint
192 return rat(-long(a
.__num
), a
.__den
)
196 return rat(abs(a
.__num
), a
.__den
)
200 return int(a
.__num
/ a
.__den
)
204 return long(a
.__num
) / long(a
.__den
)
208 return float(a
.__num
) / float(a
.__den
)
212 return complex(a
.__num
) / complex(a
.__den
)
225 return cmp(Rat(a
), b
)
232 def __coerce__(a
, b
):
237 Test function for rat module.
239 The expected output is (module some differences in floating
244 [Rat(1,2), Rat(-3,10), Rat(1,25), Rat(1,4)]
245 [Rat(-3,10), Rat(1,25), Rat(1,4), Rat(1,2)]
251 2 1.5 (3/2) (1.5+1.5j) (15707963/5000000)
255 3.5 0.5 3.0 1.33333333333 2.82842712475 1
256 (7/2) (1/2) 3 (4/3) 2.82842712475 1
257 (3.5+1.5j) (0.5-1.5j) (3+3j) (0.666666666667-0.666666666667j) (1.43248815986+2.43884761145j) 1
260 3.5 -0.5 3.0 0.75 2.25 -1
261 3.0 0.0 2.25 1.0 1.83711730709 0
262 3.0 0.0 2.25 1.0 1.83711730709 1
263 (3+1.5j) -1.5j (2.25+2.25j) (0.5-0.5j) (1.50768393746+1.04970907623j) -1
266 (7/2) (-1/2) 3 (3/4) (9/4) -1
267 3.0 0.0 2.25 1.0 1.83711730709 -1
268 3 0 (9/4) 1 1.83711730709 0
269 (3+1.5j) -1.5j (2.25+2.25j) (0.5-0.5j) (1.50768393746+1.04970907623j) -1
270 (1.5+1.5j) (1.5+1.5j)
272 (3.5+1.5j) (-0.5+1.5j) (3+3j) (0.75+0.75j) 4.5j -1
273 (3+1.5j) 1.5j (2.25+2.25j) (1+1j) (1.18235814075+2.85446505899j) 1
274 (3+1.5j) 1.5j (2.25+2.25j) (1+1j) (1.18235814075+2.85446505899j) 1
275 (3+3j) 0j 4.5j (1+0j) (-0.638110484918+0.705394566962j) 0
280 print int(a
), long(a
), float(a
), complex(a
)
282 l
= [a
+b
, a
-b
, a
*b
, a
/b
]
292 raise SystemError, 'should have been ZeroDivisionError'
293 except ZeroDivisionError:
295 print rat(2), rat(1.5), rat(3, 2), rat(1.5+1.5j
), rat(31415926,10000000)
296 list = [2, 1.5, rat(3,2), 1.5+1.5j
]
299 if type(i
) is not ComplexType
:
300 print int(i
), float(i
),
304 print i
+ j
, i
- j
, i
* j
, i
/ j
, i
** j
, cmp(i
, j
)
306 if __name__
== '__main__':