blob: 755374570611e21c6cde2bcc14612c74427a692e [file] [log] [blame]
Guido van Rossume8769491992-08-13 12:14:11 +00001# Rational numbers
2
Guido van Rossum2e611031994-10-09 22:36:28 +00003from types import *
Guido van Rossume8769491992-08-13 12:14:11 +00004
5def rat(num, den):
Guido van Rossum2e611031994-10-09 22:36:28 +00006 if type(num) == FloatType or type(den) == FloatType:
7 return num/den
Guido van Rossum7565b931993-12-17 14:23:52 +00008 return Rat(num, den)
Guido van Rossume8769491992-08-13 12:14:11 +00009
10
11def gcd(a, b):
12 while b:
13 a, b = b, a%b
14 return a
15
16
17class Rat:
18
Guido van Rossum7565b931993-12-17 14:23:52 +000019 def __init__(self, num, den):
Guido van Rossume8769491992-08-13 12:14:11 +000020 if den == 0:
21 raise ZeroDivisionError, 'rat(x, 0)'
Guido van Rossum2e611031994-10-09 22:36:28 +000022 if type(den) == FloatType or type(num) == FloatType:
23 g = float(den)
24 else:
25 g = gcd(num, den)
Guido van Rossume8769491992-08-13 12:14:11 +000026 self.num = num/g
27 self.den = den/g
Guido van Rossume8769491992-08-13 12:14:11 +000028
29 def __repr__(self):
Guido van Rossum2e611031994-10-09 22:36:28 +000030 return 'Rat(%s, %s)' % (self.num, self.den)
31
32 def __str__(self):
33 if self.den == 1:
34 return str(self.num)
35 else:
36 return '%s/%s' % (self.num, self.den)
Guido van Rossume8769491992-08-13 12:14:11 +000037
38 def __cmp__(a, b):
39 c = a-b
40 if c.num < 0:
41 return -1
42 if c.num > 0:
43 return 1
44 return 0
45
46 def __float__(self):
47 return float(self.num) / float(self.den)
48
49 def __long__(self):
50 return long(self.num) / long(self.den)
51
52 def __int__(self):
53 return int(self.num / self.den)
54
55 def __coerce__(a, b):
56 t = type(b)
Guido van Rossum2e611031994-10-09 22:36:28 +000057 if t == IntType:
58 return a, Rat(b, 1)
59 if t == LongType:
60 return a, Rat(b, 1L)
61 if t == FloatType:
62 return a, Rat(b, 1.0)
63 if t == InstanceType and a.__class__ == b.__class__:
Guido van Rossum7565b931993-12-17 14:23:52 +000064 return a, b
Guido van Rossume8769491992-08-13 12:14:11 +000065 raise TypeError, 'Rat.__coerce__: bad other arg'
Guido van Rossum7565b931993-12-17 14:23:52 +000066
Guido van Rossume8769491992-08-13 12:14:11 +000067 def __add__(a, b):
68 return rat(a.num*b.den + b.num*a.den, a.den*b.den)
69
70 def __sub__(a, b):
71 return rat(a.num*b.den - b.num*a.den, a.den*b.den)
72
73 def __mul__(a, b):
74 return rat(a.num*b.num, a.den*b.den)
75
76 def __div__(a, b):
77 return rat(a.num*b.den, a.den*b.num)
78
79 def __neg__(self):
80 return rat(-self.num, self.den)
81
82
83def test():
Guido van Rossum2e611031994-10-09 22:36:28 +000084 print Rat(-1L, 1)
85 print Rat(1, -1)
86 a = Rat(1, 10)
Guido van Rossume8769491992-08-13 12:14:11 +000087 print int(a), long(a), float(a)
Guido van Rossum2e611031994-10-09 22:36:28 +000088 b = Rat(2, 5)
Guido van Rossume8769491992-08-13 12:14:11 +000089 l = [a+b, a-b, a*b, a/b]
90 print l
91 l.sort()
92 print l
Guido van Rossum2e611031994-10-09 22:36:28 +000093 print Rat(0, 1)
Guido van Rossume8769491992-08-13 12:14:11 +000094 print a+1
95 print a+1L
96 print a+1.0
Guido van Rossumf1bbf9c1993-10-27 09:28:23 +000097 try:
Guido van Rossum2e611031994-10-09 22:36:28 +000098 print Rat(1, 0)
Guido van Rossumf1bbf9c1993-10-27 09:28:23 +000099 raise SystemError, 'should have been ZeroDivisionError'
100 except ZeroDivisionError:
101 print 'OK'
Guido van Rossume8769491992-08-13 12:14:11 +0000102
Guido van Rossum7565b931993-12-17 14:23:52 +0000103test()