Guido van Rossum | e876949 | 1992-08-13 12:14:11 +0000 | [diff] [blame] | 1 | # Rational numbers |
| 2 | |
Guido van Rossum | 2e61103 | 1994-10-09 22:36:28 +0000 | [diff] [blame] | 3 | from types import * |
Guido van Rossum | e876949 | 1992-08-13 12:14:11 +0000 | [diff] [blame] | 4 | |
| 5 | def rat(num, den): |
Guido van Rossum | 2e61103 | 1994-10-09 22:36:28 +0000 | [diff] [blame] | 6 | if type(num) == FloatType or type(den) == FloatType: |
| 7 | return num/den |
Guido van Rossum | 7565b93 | 1993-12-17 14:23:52 +0000 | [diff] [blame] | 8 | return Rat(num, den) |
Guido van Rossum | e876949 | 1992-08-13 12:14:11 +0000 | [diff] [blame] | 9 | |
| 10 | |
| 11 | def gcd(a, b): |
| 12 | while b: |
| 13 | a, b = b, a%b |
| 14 | return a |
| 15 | |
| 16 | |
| 17 | class Rat: |
| 18 | |
Guido van Rossum | 7565b93 | 1993-12-17 14:23:52 +0000 | [diff] [blame] | 19 | def __init__(self, num, den): |
Guido van Rossum | e876949 | 1992-08-13 12:14:11 +0000 | [diff] [blame] | 20 | if den == 0: |
| 21 | raise ZeroDivisionError, 'rat(x, 0)' |
Guido van Rossum | 2e61103 | 1994-10-09 22:36:28 +0000 | [diff] [blame] | 22 | if type(den) == FloatType or type(num) == FloatType: |
| 23 | g = float(den) |
| 24 | else: |
| 25 | g = gcd(num, den) |
Guido van Rossum | e876949 | 1992-08-13 12:14:11 +0000 | [diff] [blame] | 26 | self.num = num/g |
| 27 | self.den = den/g |
Guido van Rossum | e876949 | 1992-08-13 12:14:11 +0000 | [diff] [blame] | 28 | |
| 29 | def __repr__(self): |
Guido van Rossum | 2e61103 | 1994-10-09 22:36:28 +0000 | [diff] [blame] | 30 | 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 Rossum | e876949 | 1992-08-13 12:14:11 +0000 | [diff] [blame] | 37 | |
| 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 Rossum | 2e61103 | 1994-10-09 22:36:28 +0000 | [diff] [blame] | 57 | 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 Rossum | 7565b93 | 1993-12-17 14:23:52 +0000 | [diff] [blame] | 64 | return a, b |
Guido van Rossum | e876949 | 1992-08-13 12:14:11 +0000 | [diff] [blame] | 65 | raise TypeError, 'Rat.__coerce__: bad other arg' |
Guido van Rossum | 7565b93 | 1993-12-17 14:23:52 +0000 | [diff] [blame] | 66 | |
Guido van Rossum | e876949 | 1992-08-13 12:14:11 +0000 | [diff] [blame] | 67 | 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 | |
| 83 | def test(): |
Guido van Rossum | 2e61103 | 1994-10-09 22:36:28 +0000 | [diff] [blame] | 84 | print Rat(-1L, 1) |
| 85 | print Rat(1, -1) |
| 86 | a = Rat(1, 10) |
Guido van Rossum | e876949 | 1992-08-13 12:14:11 +0000 | [diff] [blame] | 87 | print int(a), long(a), float(a) |
Guido van Rossum | 2e61103 | 1994-10-09 22:36:28 +0000 | [diff] [blame] | 88 | b = Rat(2, 5) |
Guido van Rossum | e876949 | 1992-08-13 12:14:11 +0000 | [diff] [blame] | 89 | l = [a+b, a-b, a*b, a/b] |
| 90 | print l |
| 91 | l.sort() |
| 92 | print l |
Guido van Rossum | 2e61103 | 1994-10-09 22:36:28 +0000 | [diff] [blame] | 93 | print Rat(0, 1) |
Guido van Rossum | e876949 | 1992-08-13 12:14:11 +0000 | [diff] [blame] | 94 | print a+1 |
| 95 | print a+1L |
| 96 | print a+1.0 |
Guido van Rossum | f1bbf9c | 1993-10-27 09:28:23 +0000 | [diff] [blame] | 97 | try: |
Guido van Rossum | 2e61103 | 1994-10-09 22:36:28 +0000 | [diff] [blame] | 98 | print Rat(1, 0) |
Guido van Rossum | f1bbf9c | 1993-10-27 09:28:23 +0000 | [diff] [blame] | 99 | raise SystemError, 'should have been ZeroDivisionError' |
| 100 | except ZeroDivisionError: |
| 101 | print 'OK' |
Guido van Rossum | e876949 | 1992-08-13 12:14:11 +0000 | [diff] [blame] | 102 | |
Guido van Rossum | 7565b93 | 1993-12-17 14:23:52 +0000 | [diff] [blame] | 103 | test() |