Module RationalNumbers {
Class Rational {
numerator as decimal, denominator as decimal
gcd=lambda->0
lcm=lambda->0
operator "+" {
Read l
denom=.lcm(l.denominator, .denominator)
.numerator<=denom/l.denominator*l.numerator+denom/.denominator*.numerator
if .numerator==0 then denom=1
.denominator<=denom
}
Operator Unary {
.numerator-!
}
Operator "-" {
Read l
Call Operator "+", -l
}
Operator "*" {
Read l
g1=.gcd(l.numerator,.denominator)
g2=.gcd(.numerator, l.denominator)
Push l.numerator/g1*.numerator/g2
Push l.denominator/g2*.denominator/g1
Read .denominator, .numerator
}
Function Inverse {
if .numerator==0 then Error "Division by zero"
ret=This
sign=sgn(ret.numerator) : if sign<0 then ret.numerator-!
swap ret.numerator, ret.denominator
if sign<0 then ret.numerator-!
=ret
}
Operator "/" {
Read l
call operator "*", l.inverse()
}
Function Power {
Read pow as long
ret=This
ret.numerator<=.numerator^pow
ret.denominator<=.denominator^pow
=ret
}
Operator "=" {
Read l
Def boolean T=True, F=False
if Abs(sgn(l.numerator))+Abs(sgn(.numerator))=0 then Push T: exit
if sgn(l.numerator) <>sgn(.numerator) then Push F : exit
pcomp=l/this
PUSH pcomp.numerator=1 and pcomp.denominator=1
}
Operator ">" {
Read l
Def boolean F
if Abs(sgn(l.numerator))+Abs(sgn(.numerator))=0 then Push F: exit
if sgn(l.numerator)=0 then {
PUSH .numerator>0
} Else {
pcomp=this/l
PUSH pcomp.real>1
}
}
Operator ">=" {
Read l
if sgn(l.numerator)=0 then {
PUSH .numerator>=0
} Else {
pcomp=this/l
PUSH pcomp.real>=1
}
}
Operator "<" {
Read l
Def boolean F
if Abs(sgn(l.numerator))+Abs(sgn(.numerator))=0 then Push F: exit
if sgn(l.numerator)=0 then {
PUSH .numerator<0
} Else {
pcomp=this/l
PUSH pcomp.real<1
}
}
Operator "<=" {
Read l
if sgn(l.numerator)=0 then {
PUSH .numerator<=0
} Else {
pcomp=this/l
PUSH pcomp.real<=1
}
}
Operator "<>" {
Read l
if sgn(l.numerator)=0 then {
PUSH .numerator<>0
} Else {
pcomp=this/l
PUSH pcomp.real<>1
}
}
Group Real {
value {
link parent numerator, denominator to n, d
=n/d
}
}
Group ToString$ {
value {
link parent numerator, denominator to n, d
=Str$(n)+"/"+Str$(d,"")
}
}
class:
Module Rational (.numerator, .denominator) {
if .denominator=0 then Error "Zero denominator"
sgn=Sgn(.numerator)*Sgn(.denominator)
.denominator<=abs(.denominator)
.numerator<=abs(.numerator)*sgn
gcd1=lambda (a as decimal, b as decimal) -> {
if a<b then swap a,b
g=a mod b
while g {
a=b:b=g: g=a mod b
}
=abs(b)
}
gdcval=gcd1(abs(.numerator), .denominator)
if gdcval<.denominator and gdcval<>0 then
.denominator/=gdcval
.numerator/=gdcval
end if
.gcd<=gcd1
.lcm<=lambda gcd=gcd1 (a as decimal, b as decimal) -> {
=a/gcd(a,b)*b
}
}
}
Print rational(-3,3)<>rational(-3,3)
M=Rational(10, 150)
N=Rational(2, 4)
Z=M+N
Print Z.numerator, Z.denominator
Print 10/150@+2/4@
Print Z.real
Z=-M+N
Print Z.numerator, Z.denominator
Print -10/150@+2/4@
Print Z.real
Z=M-N
Print Z.numerator, Z.denominator
Print 10/150@-2/4@
Print Z.real
Z=M*N
Print Z.numerator, Z.denominator
Print (10/150@)*(2/4@)
Print Z.real
Z=M/N
Print Z.numerator, Z.denominator
Print (10/150@)/(2/4@)
Print Z.real
Z=Z.Power(2)
Print Z.real
Print Z=Z
Print Z=N
Print Z=-Z
ZZ=-Z
Print ZZ=ZZ
Print -Z=-Z
Print Z.numerator, Z.denominator
Print Z.real, Z.tostring$
\\ Array of rational numbers
Dim K(100)=rational(1,1)
M=K(4)+K(3)
Print M.real
Print K(4).toString$
}
RationalNumbers