# M2000 Interpreter rational numbers

## 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 "*" {                  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 "Positive only denominator"                  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)                  }                  .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/[email protected]+2/[email protected]      Print Z.real      Z=-M+N      Print Z.numerator, Z.denominator      Print -10/[email protected]+2/[email protected]      Print Z.real      Z=M-N      Print Z.numerator, Z.denominator      Print 10/[email protected]/[email protected]      Print Z.real      Z=M*N      Print Z.numerator, Z.denominator      Print (10/[email protected])*(2/[email protected])      Print Z.real      Z=M/N      Print Z.numerator, Z.denominator      Print (10/[email protected])/(2/[email protected])      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 `