Task

Create a reasonably complete implementation of rational arithmetic in the particular language using the idioms of the language.



Example

Define a new type called frac with binary operator "//" of two integers that returns a structure made up of the numerator and the denominator (as per a rational number).

Further define the appropriate rational unary operators abs and '-', with the binary operators for addition '+', subtraction '-', multiplication '×', division '/', integer division '÷', modulo division, the comparison operators (e.g. '<', '≤', '>', & '≥') and equality operators (e.g. '=' & '≠').

Define standard coercion operators for casting int to frac etc.

If space allows, define standard increment and decrement operators (e.g. '+:=' & '-:=' etc.).

Finally test the operators:
Use the new type frac to find all perfect numbers less than 219 by summing the reciprocal of the factors.



Related task

   Perfect Numbers


 
n=2^19
for testNumber=1 to n
    sum$=castToFraction$(0)
    for factorTest=1 to sqr(testNumber)
        if GCD(factorTest,testNumber)=factorTest then sum$=add$(sum$,add$(reciprocal$(castToFraction$(factorTest)),reciprocal$(castToFraction$(testNumber/factorTest))))
    next factorTest
    if equal(sum$,castToFraction$(2))=1 then print testNumber
next testNumber
end
 
function abs$(a$)
    aNumerator=val(word$(a$,1,"/"))
    aDenominator=val(word$(a$,2,"/"))
    bNumerator=abs(aNumerator)
    bDenominator=abs(aDenominator)
    b$=str$(bNumerator)+"/"+str$(bDenominator)
    abs$=simplify$(b$)
end function
 
function negate$(a$)
    aNumerator=val(word$(a$,1,"/"))
    aDenominator=val(word$(a$,2,"/"))
    bNumerator=-1*aNumerator
    bDenominator=aDenominator
    b$=str$(bNumerator)+"/"+str$(bDenominator)
    negate$=simplify$(b$)
end function
 
function add$(a$,b$)
    aNumerator=val(word$(a$,1,"/"))
    aDenominator=val(word$(a$,2,"/"))
    bNumerator=val(word$(b$,1,"/"))
    bDenominator=val(word$(b$,2,"/"))
    cNumerator=(aNumerator*bDenominator+bNumerator*aDenominator)
    cDenominator=aDenominator*bDenominator
    c$=str$(cNumerator)+"/"+str$(cDenominator)
    add$=simplify$(c$)
end function
 
function subtract$(a$,b$)
    aNumerator=val(word$(a$,1,"/"))
    aDenominator=val(word$(a$,2,"/"))
    bNumerator=val(word$(b$,1,"/"))
    bDenominator=val(word$(b$,2,"/"))
    cNumerator=(aNumerator*bDenominator-bNumerator*aDenominator)
    cDenominator=aDenominator*bDenominator
    c$=str$(cNumerator)+"/"+str$(cDenominator)
    subtract$=simplify$(c$)
end function
 
function multiply$(a$,b$)
    aNumerator=val(word$(a$,1,"/"))
    aDenominator=val(word$(a$,2,"/"))
    bNumerator=val(word$(b$,1,"/"))
    bDenominator=val(word$(b$,2,"/"))
    cNumerator=aNumerator*bNumerator
    cDenominator=aDenominator*bDenominator
    c$=str$(cNumerator)+"/"+str$(cDenominator)
    multiply$=simplify$(c$)
end function
 
function divide$(a$,b$)
    divide$=multiply$(a$,reciprocal$(b$))
end function
 
function simplify$(a$)
    aNumerator=val(word$(a$,1,"/"))
    aDenominator=val(word$(a$,2,"/"))
    gcd=GCD(aNumerator,aDenominator)
    if aNumerator<0 and aDenominator<0 then gcd=-1*gcd
    bNumerator=aNumerator/gcd
    bDenominator=aDenominator/gcd
    b$=str$(bNumerator)+"/"+str$(bDenominator)
    simplify$=b$
end function
 
function reciprocal$(a$)
    aNumerator=val(word$(a$,1,"/"))
    aDenominator=val(word$(a$,2,"/"))
    reciprocal$=str$(aDenominator)+"/"+str$(aNumerator)
end function
 
function equal(a$,b$)
    if simplify$(a$)=simplify$(b$) then equal=1:else equal=0
end function
 
function castToFraction$(a)
    do
        exp=exp+1
        a=a*10
    loop until a=int(a)
    castToFraction$=simplify$(str$(a)+"/"+str$(10^exp))
end function
 
function castToReal(a$)
    aNumerator=val(word$(a$,1,"/"))
    aDenominator=val(word$(a$,2,"/"))
    castToReal=aNumerator/aDenominator
end function
 
function castToInt(a$)
    castToInt=int(castToReal(a$))
end function
 
function GCD(a,b)
    if a=0 then
        GCD=1
    else
        if a>=b then
            while b
                c = a
                a = b
                b = c mod b
                GCD = abs(a)
            wend
        else
            GCD=GCD(b,a)
        end if
    end if
end function
 