M2000 Interpreter rational numbers
Appearance
M2000 Interpreter
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 high "*" {
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 high"/" {
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
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
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
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 .denominator<=1
while frac(.numerator)<>0 {
.numerator*=10@
.denominator*=10@
}
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) ' false
M=Rational(10, 150)
N=Rational(2, 4)
Print "M.real+N.real=";M.real+N.real
Print "Z=M+N"
Z=M+N
Print 10/150@+2/4@
Print "Z.real="; Z.real
Print "(";M.numerator;"/"; M.denominator;") + (";N.numerator;"/"; N.denominator;") = (";Z.numerator;"/";Z.denominator;")"
Print M.tostring$+ " +"+N.tostring$+" ="+Z.tostring$
Print -10/150@+2/4@
Z=-M+N
Print "-"+M.tostring$+ " +"+N.tostring$+" ="+Z.tostring$
Print Z.numerator, Z.denominator, 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.tostring$
Print Z.real
Print "Z power 2 = ";
Z=Z.Power(2)
Print Z.real
Print z.tostring$;" = ";eval(z.tostring$)
Print Z=Z
Print Z=N, " SHOULD BE FALSE" ' false
Print Z=-Z , " SHOULD BE FALSE" ' false
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$
pk->(Z)
Print pk=>toString$+" +"
zzz=k(4)+pk
Print zzz.toString$+ " ="+K(4).toString$+" +"+pk=>toString$
zzz=Rational(10,1)+Rational(3,1)*Rational(2,1)
Print zzz.toString$, zzz.real=16
zzz=Rational(10,1)*Rational(3,1)+Rational(2,1)
Print zzz.toString$, zzz.real=32
}
RationalNumbers