Klasse für Brüche
Verfasst: Sonntag 27. April 2003, 14:48
Wegen der Diskussion um die Gleitkommazahlen, ahbe ich mal nen Klasse für Brüche geschrieben, die sich wie eine Zahl handhaben lässt. Zur Initialisierung gibt man den Zähler, den Nenner und einen Parameter an. Letzerer gibt an, ob bei Rufen von int oder long auch aufgerundet werden soll (ab .5), oder nur abgerundet werden soll, wie es int und long normalerweise tun.
Hat aber noch ein paar Mängel: man kann zwar ohne Probleme rechnen, aber sie verträgt sich nicht mit Integern in dieser Form:
Wie kann ich der Klasse sagen, sie soll prüfen, ob das andere ne Instanz von Bruch ist, oder eine normale Zahl ? (welche sich ja als bruch(x,1) darstellen ließe)
Code: Alles auswählen
class bruch:
def __init__(self,z=1,n=1,round=1):
self.z,self.n=ifelse(n>=0,[z,n],[-z,-n])
t = self.__ggt__(self.z,self.n)
self.z,self.n=self.z/t,self.n/t
if self.n==0:
raise ZeroDivisionError, "integer division or modulo by zero"
self.round=round
def round(state=1):
self.round=state
def gettuple():
return self.z,self.n
def __ggt__(self,x,y):
while y > 0:
rest = x % y
x = y
y = rest
return x
def __kgv__(self,x,y):
return (x/self.__ggt__(x,y))*y
def __round__(self,x):
return long(x+ 0.5 * ((x > 0) or -1))
def __add__(self,other):
zs = self.z * other.n + other.z * self.n
ns = self.n * other.n
t = self.__ggt__(zs,ns)
return bruch(zs/t, ns/t)
def __div__(self,other):
zs = self.z * other.n
ns = self.n * other.z
t = self.__ggt__(zs,ns)
return bruch(zs/t, ns/t)
def __divmod__(self,other):
return (self/other,self%other)
def __mod__(self,other):
if other==0 or other.z==0:
raise ZeroDivisionError, "integer division or modulo by zero"
ns=self.__kgv__(self.n,other.n)
self.z=self.z*(ns/self.n)
other.z=other.z*(ns/other.n)
return bruch(self.z%other.z,ns)
def __mul__(self,other):
zs = self.z * other.z
ns = self.n * other.n
t = self.__ggt__(zs,ns)
return bruch(zs/t, ns/t)
def __pow__(self,other):
other=long(other)
if other>=0:
return bruch(self.z**other,self.n**other)
else:
return bruch(self.n**other,self.z**other)
def __sub__(self,other):
zs = self.z * other.n - other.z * self.n
ns = self.n * other.n
t = self.__ggt__(zs,ns)
return bruch(zs/t, ns/t)
def __abs__(self):
return bruch(abs(self.z),abs(self.n))
def __float__(self):
return float(self.z)/float(self.n)
def __int__(self):
return int(self.__long__())
def __long__(self):
if self.n==1:
return long(self.z)
elif self.round:
return self.__round__(float(self.z)/float(self.n))
else:
return long(float(self.z)/float(self.n))
def __neg__(self):
return bruch(-self.z,self.n)
def __pos__(self):
return bruch(self.z,self.n)
def __repr__(self):
return "bruch(%i,%i)"%(self.z,self.n)
def __str__(self):
return "(%i / %i)"%(self.z,self.n)
Code: Alles auswählen
>>> x=bruch(1,3)
>>> x
bruch(1,3)
>>> x*bruch(3,1)
bruch(1,1)
>>> x*3
Traceback (most recent call last):
File "<pyshell#6>", line 1, in ?
x*3
File "C:\Python22\lib\site-packages\utils.py", line 77, in __mul__
zs = self.z * other.z
AttributeError: 'int' object has no attribute 'z'