How to resolve the algorithm Arithmetic/Rational step by step in the Action! programming language
How to resolve the algorithm Arithmetic/Rational step by step in the Action! programming language
Table of Contents
Problem Statement
Create a reasonably complete implementation of rational arithmetic in the particular language using the idioms of the language.
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.
Let's start with the solution:
Step by Step solution about How to resolve the algorithm Arithmetic/Rational step by step in the Action! programming language
Source code in the action! programming language
INCLUDE "D2:REAL.ACT" ;from the Action! Tool Kit
TYPE Frac=[INT num,den]
REAL half
PROC PrintFrac(Frac POINTER x)
PrintI(x.num) Put('/) PrintI(x.den)
RETURN
INT FUNC Gcd(INT a,b)
INT tmp
IF a
tmp=a a=b b=tmp
FI
WHILE b#0
DO
tmp=a MOD b
a=b
b=tmp
OD
RETURN (a)
PROC Init(INT n,d Frac POINTER res)
IF d>0 THEN
res.num=n res.den=d
ELSEIF d<0 THEN
res.num=-n res.den=-d
ELSE
Print("Denominator cannot be zero!")
Break()
FI
RETURN
PROC Assign(Frac POINTER x,res)
Init(x.num,x.den,res)
RETURN
PROC Neg(Frac POINTER x,res)
Init(-x.num,x.den,res)
RETURN
PROC Inverse(Frac POINTER x,res)
Init(x.den,x.num)
RETURN
PROC Abs(Frac POINTER x,res)
IF x.num<0 THEN
Neg(x,res)
ELSE
Assign(x,res)
FI
RETURN
PROC Add(Frac POINTER x,y,res)
INT common,xDen,yDen
common=Gcd(x.den,y.den)
xDen=x.den/common
yDen=y.den/common
Init(x.num*yDen+y.num*xDen,xDen*y.den,res)
RETURN
PROC Sub(Frac POINTER x,y,res)
Frac n
Neg(y,n) Add(x,n,res)
RETURN
PROC Mult(Frac POINTER x,y,res)
Init(x.num*y.num,x.den*y.den,res)
RETURN
PROC Div(Frac POINTER x,y,res)
Frac i
Inverse(y,i) Mult(x,i,res)
RETURN
BYTE FUNC Greater(Frac POINTER x,y)
Frac diff
Sub(x,y,diff)
IF diff.num>0 THEN
RETURN (1)
FI
RETURN (0)
BYTE FUNC Less(Frac POINTER x,y)
RETURN (Greater(y,x))
BYTE FUNC GreaterEqual(Frac POINTER x,y)
Frac diff
Sub(x,y,diff)
IF diff.num>=0 THEN
RETURN (1)
FI
RETURN (0)
BYTE FUNC LessEqual(Frac POINTER x,y)
RETURN (GreaterEqual(y,x))
BYTE FUNC Equal(Frac POINTER x,y)
Frac diff
Sub(x,y,diff)
IF diff.num=0 THEN
RETURN (1)
FI
RETURN (0)
BYTE FUNC NotEqual(Frac POINTER x,y)
IF Equal(x,y) THEN
RETURN (0)
FI
RETURN (1)
INT FUNC Sqrt(INT x)
REAL r1,r2
IF x=0 THEN
RETURN (0)
FI
IntToReal(x,r1)
Power(r1,half,r2)
RETURN (RealToInt(r2))
PROC Main()
DEFINE MAXINT="32767"
INT i,f,max2
Frac sum,tmp1,tmp2,tmp3,one
Put(125) PutE() ;clear screen
ValR("0.5",half)
Init(1,1,one)
FOR i=2 TO MAXINT
DO
Init(1,i,sum) ;sum=1/i
max2=Sqrt(i)
FOR f=2 TO max2
DO
IF i MOD f=0 THEN
Init(1,f,tmp1) ;tmp1=1/f
Add(sum,tmp1,tmp2) ;tmp2=sum+1/f
Init(f,i,tmp3) ;tmp3=f/i
Add(tmp2,tmp3,sum) ;sum=sum+1/f+f/i
FI
OD
IF Equal(sum,one) THEN
PrintF("%I is perfect%E",i)
FI
OD
RETURN
You may also check:How to resolve the algorithm Terminal control/Coloured text step by step in the Haskell programming language
You may also check:How to resolve the algorithm Continued fraction step by step in the J programming language
You may also check:How to resolve the algorithm Sum of a series step by step in the Erlang programming language
You may also check:How to resolve the algorithm Deceptive numbers step by step in the langur programming language
You may also check:How to resolve the algorithm Sum and product of an array step by step in the Emacs Lisp programming language