blob: d10e4dfac43dd961893d25e4b0839931509b5d61 [file] [log] [blame]
Guido van Rossume8769491992-08-13 12:14:11 +00001# Rational numbers
2
3
4def rat(num, den):
Guido van Rossum7565b931993-12-17 14:23:52 +00005 return Rat(num, den)
Guido van Rossume8769491992-08-13 12:14:11 +00006
7
8def gcd(a, b):
9 while b:
10 a, b = b, a%b
11 return a
12
13
14class Rat:
15
Guido van Rossum7565b931993-12-17 14:23:52 +000016 def __init__(self, num, den):
Guido van Rossume8769491992-08-13 12:14:11 +000017 if den == 0:
18 raise ZeroDivisionError, 'rat(x, 0)'
19 g = gcd(num, den)
20 self.num = num/g
21 self.den = den/g
Guido van Rossume8769491992-08-13 12:14:11 +000022
23 def __repr__(self):
24 return 'rat' + `self.num, self.den`
25
26 def __cmp__(a, b):
27 c = a-b
28 if c.num < 0:
29 return -1
30 if c.num > 0:
31 return 1
32 return 0
33
34 def __float__(self):
35 return float(self.num) / float(self.den)
36
37 def __long__(self):
38 return long(self.num) / long(self.den)
39
40 def __int__(self):
41 return int(self.num / self.den)
42
43 def __coerce__(a, b):
44 t = type(b)
45 if t == type(0):
46 return a, rat(b, 1)
47 if t == type(0L):
48 return a, rat(b, 1L)
49 if t == type(0.0):
50 return a.__float__(), b
Guido van Rossum7565b931993-12-17 14:23:52 +000051 if t == type(a) and a.__class__ == b.__class__:
52 return a, b
Guido van Rossume8769491992-08-13 12:14:11 +000053 raise TypeError, 'Rat.__coerce__: bad other arg'
Guido van Rossum7565b931993-12-17 14:23:52 +000054
Guido van Rossume8769491992-08-13 12:14:11 +000055 def __add__(a, b):
Guido van Rossumf1bbf9c1993-10-27 09:28:23 +000056 if type(b) <> type(a):
57 a, b = a.__coerce__(b)
58 return a + b
Guido van Rossume8769491992-08-13 12:14:11 +000059 return rat(a.num*b.den + b.num*a.den, a.den*b.den)
60
61 def __sub__(a, b):
62 return rat(a.num*b.den - b.num*a.den, a.den*b.den)
63
64 def __mul__(a, b):
Guido van Rossumf1bbf9c1993-10-27 09:28:23 +000065 if type(b) <> type(a):
66 a, b = a.__coerce__(b)
67 return a * b
Guido van Rossume8769491992-08-13 12:14:11 +000068 return rat(a.num*b.num, a.den*b.den)
69
70 def __div__(a, b):
71 return rat(a.num*b.den, a.den*b.num)
72
73 def __neg__(self):
74 return rat(-self.num, self.den)
75
76
77def test():
78 print rat(-1L, 1)
79 print rat(1, -1)
80 a = rat(1, 10)
81 print int(a), long(a), float(a)
82 b = rat(2, 5)
83 l = [a+b, a-b, a*b, a/b]
84 print l
85 l.sort()
86 print l
87 print rat(0, 1)
Guido van Rossume8769491992-08-13 12:14:11 +000088 print a+1
89 print a+1L
90 print a+1.0
Guido van Rossumf1bbf9c1993-10-27 09:28:23 +000091 try:
92 print rat(1, 0)
93 raise SystemError, 'should have been ZeroDivisionError'
94 except ZeroDivisionError:
95 print 'OK'
Guido van Rossume8769491992-08-13 12:14:11 +000096
Guido van Rossum7565b931993-12-17 14:23:52 +000097test()