with text_io,integer_io; use text_io,integer_io; with Multprec_Natural_Numbers; use Multprec_Natural_Numbers; with Multprec_Natural_Numbers_io; use Multprec_Natural_Numbers_io; with Multprec_Random_Numbers; use Multprec_Random_Numbers; procedure ts_natnum is -- DESCRIPTION : -- This procedure offers interactive and random testers for the -- operations with multi-precision natural numbers. See the menu below. procedure Test_Creation is n : natural; nn : Natural_Number; ans : character; begin put_line("Testing the creation of a natural number."); loop put("Give a standard natural number : "); get(n); nn := Create(n); put("-> as natural number : "); put(nn); new_line; Clear(nn); put("Do you want more tests ? (y/n) "); get(ans); exit when ans /= 'y'; end loop; end Test_Creation; procedure Test_io is ans : character; n : Natural_Number; begin put_line("Testing the input/output operations."); loop put("Give a number : "); get(n); put("-> your number : "); put(n); new_line; put("#decimal places : "); put(Decimal_Places(n),1); new_line; put("Do you want more tests ? (y/n) "); get(ans); exit when ans /= 'y'; end loop; end Test_io; procedure Test_Compare ( n1 : in Natural_Number; n2 : in natural ) is begin if Equal(n1,n2) then put_line("The numbers are equal."); else put_line("The numbers are different."); end if; if n1 < n2 then put_line("First is less than second."); else put_line("First not less than second."); end if; if n1 > n2 then put_line("First is greater than second."); else put_line("First is not greater than second."); end if; end Test_Compare; procedure Test_Compare ( n1 : in natural; n2 : in Natural_Number ) is begin if Equal(n2,n1) then put_line("Both numbers are equal."); else put_line("The numbers are different."); end if; if n1 < n2 then put_line("First is less than second."); else put_line("First not less than second."); end if; if n1 > n2 then put_line("First is greater than second."); else put_line("First is not greater than second."); end if; end Test_Compare; procedure Test_Compare ( n1,n2 : in Natural_Number ) is begin if Equal(n1,n2) then put_line("Both numbers are equal."); else put_line("The numbers are different."); end if; if n1 < n2 then put_line("First is less than second."); else put_line("First not less than second."); end if; if n1 > n2 then put_line("First is greater than second."); else put_line("First is not greater than second."); end if; end Test_Compare; procedure Test_Comparison is ans : character; n1,n2 : Natural_Number; -- n1 : natural; begin put_line("Testing the comparison operations."); loop put("Give 1st number n1 : "); get(n1); put("-> n1 : "); put(n1); new_line; put("Give 2nd number n2 : "); get(n2); put("-> n2 : "); put(n2); new_line; Test_Compare(n1,n2); Copy(n1,n2); put_line("Tests after copying : "); Test_Compare(n1,n2); Div(n1,10); put_line("After dividing n1 by 10 :"); put(" n1 : "); put(n1); new_line; put(" n2 : "); put(n2); new_line; put("Do you want more tests ? (y/n) "); get(ans); exit when ans /= 'y'; end loop; end Test_Comparison; procedure Test_Addition is -- NOTE : to test n1+n2 with n2 a standard natural, -- just change the declaration of n2. ans : character; n1,n2,sum1,sum2 : Natural_Number; begin put_line("Testing the addition operations."); loop put("Give 1st number : "); get(n1); put("-> your 1st number n1 : "); put(n1); new_line; put("Give 2nd number : "); get(n2); put("-> your 2nd number n2 : "); put(n2); new_line; sum1 := n1+n2; put("n1+n2 : "); put(sum1); new_line; sum2 := n2+n1; put("n2+n1 : "); put(sum2); new_line; if Equal(sum1,sum2) then put_line("Test on commutativity is successful."); else put_line("Failure, sum not commutative: bug!"); end if; put("Do you want more tests ? (y/n) "); get(ans); exit when ans /= 'y'; end loop; end Test_Addition; function Mult_by_Add ( n1 : Natural_Number; n2 : natural ) return Natural_Number is -- DESCRIPTION : -- Does the multiplication by adding up n1 to itself as many times -- as the number n2. Only to be used as test of course. res : Natural_Number; begin if n2 = 0 then return res; else Copy(n1,res); for i in 1..n2-1 loop Add(res,n1); end loop; return res; end if; end Mult_by_Add; function Mult_by_Add ( n1,n2 : Natural_Number ) return Natural_Number is -- DESCRIPTION : -- Does the multiplication by adding up n1 to itself as many times -- as the number n2. Only to be used as test of course. -- This can be quite time consuming as n2 gets large. res,cnt : Natural_Number; begin if Equal(n2,0) then return res; else Copy(n1,res); cnt := Create(1); while not Equal(cnt,n2) loop Add(res,n1); Add(cnt,1); end loop; Clear(cnt); return res; end if; end Mult_by_Add; procedure Test_Multiplication is -- NOTE : to test n1*n2 with n2 : natural, change the declaration of n2. ans : character; n1,prod1,prod2,prod3 : Natural_Number; n2 : natural; begin put_line("Testing the multiplication operations."); loop put("Give 1st number : "); get(n1); put("-> your 1st number : "); put(n1); new_line; put("Give 2nd number : "); get(n2); put("-> your 2nd number : "); put(n2); new_line; prod1 := n1*n2; put("Product n1*n2 : "); put(prod1); new_line; prod2 := n2*n1; put("Product n2*n1 : "); put(prod2); new_line; if Equal(prod1,prod2) then put_line("Test on commutativity is successful."); else put_line("Failure, product not commutative: bug!"); end if; put("Do you want multiplication by addition ? (y/n) "); get(ans); if ans = 'y' then put_line("Testing the multiplication by addition. Be patient..."); prod3 := Mult_by_Add(n1,n2); put("After adding "); put(n2); put(" times : "); put(prod3); new_line; if Equal(prod1,prod3) then put_line("Test of multiplication is successful."); else put_line("Failure, bug detected."); end if; end if; put("Do you want more tests ? (y/n) "); get(ans); exit when ans /= 'y'; end loop; end Test_Multiplication; procedure Test_Exponentiation is ans : character; n,e1,e2,exp1,exp2,prod,expo : Natural_Number; begin put_line("Testing the exponentiation operations."); loop put("Give a number : "); get(n); put("-> your number n : "); put(n); new_line; put("Give 1st exponent : "); get(e1); put("-> your 1st exponent e1 : "); put(e1); new_line; exp1 := n**e1; put("n**e1 : "); put(exp1); new_line; put("Give 2nd exponent : "); get(e2); put("-> your 2nd exponent e2 : "); put(e2); new_line; exp2 := n**e2; put("n**e2 : "); put(exp2); new_line; prod := exp1*exp2; put("(n**e1)*(n**e2) : "); put(prod); new_line; expo := n**(e1+e2); put("n**(e1+e2) : "); put(expo); new_line; if Equal(prod,expo) then put_line("Test of exponentiation is successful."); else put_line("Failure, bug detected."); end if; put("Do you want more tests ? (y/n) "); get(ans); exit when ans /= 'y'; end loop; end Test_Exponentiation; procedure Test_Subtraction is ans : character; n1,n2,diff : Natural_Number; begin put_line("Testing the subtraction operations."); loop put("Give 1st number : "); get(n1); put("-> your 1st number n1 : "); put(n1); new_line; put("Give 2nd number : "); get(n2); put("-> your 2nd number n2 : "); put(n2); new_line; diff := n1-n2; put("n1 - n2 : "); put(diff); new_line; Add(diff,n2); put("(n1-n2)+n2 : "); put(diff); new_line; if Equal(diff,n1) then put_line("Test of subtraction is successful."); else put_line("Failure, bug detected."); end if; put("Do you want more tests ? (y/n) "); get(ans); exit when ans /= 'y'; end loop; end Test_Subtraction; procedure Divide10 ( n : in Natural_Number ) is -- DESCRIPTION : -- Checks whether the number n is divisible by 1..10. quot,prod : Natural_Number; rest : natural; begin put("n : "); put(n); new_line; for i in 1..10 loop rest := Rmd(n,i); quot := n/i; if rest = 0 then put("Divisible by "); put(i,1); else put("Not divisible by "); put(i,1); end if; put(" rest : "); put(rest,1); new_line; put("quotient : "); put(quot); new_line; prod := quot*i + rest; if Equal(prod,n) then put_line("Test on Remainder/Division is successful."); else put_line("Failure, bug detected."); end if; end loop; end Divide10; procedure Test_Division is ans : character; n1,n2,quot,prod,rest : Natural_Number; -- n2,rest : natural; begin put_line("Testing the division operations."); loop put("Give 1st number : "); get(n1); put("-> your 1st number n1 : "); put(n1); new_line; put("Give 2nd number : "); get(n2); put("-> your 2nd number n2 : "); put(n2); new_line; prod := n1*n2; put("n1*n2 : "); put(prod); new_line; quot := prod/n2; rest := Rmd(prod,n2); put("(n1*n2)/n2 : "); put(quot); new_line; put("Remainder : "); put(rest); new_line; if Equal(quot,n1) and Equal(rest,0) then put_line("Test of division is successful."); else put_line("Failure, bug detected."); end if; Div(n1,n2,quot,rest); put("n1/n2 : "); put(quot); new_line; put("rest : "); put(rest); new_line; prod := quot*n2 + rest; if Equal(prod,n1) then put_line("Test of division/remainder computation is successful."); else put_line("Failure, bug detected."); end if; -- if n2 <= 10 -- then Divide10(n1); -- end if; put("Do you want more tests ? (y/n) "); get(ans); exit when ans /= 'y'; end loop; end Test_Division; procedure Random_Addition_and_Subtraction ( sz1,sz2 : in natural ) is -- DESCRIPTION : -- Three tests are performed: -- 1) n1+n2-n2 = n1, with "+" and "-". -- 2) Add(n1,n2) is the same as n1 := n1+n2? -- 3) Sub(n1+n2,n1) leads to n2? n1,n2,sum1,sum2 : Natural_Number; procedure Report_Bug is begin new_line; put(" n1 : "); put(n1); new_line; put(" n2 : "); put(n2); new_line; end Report_Bug; begin n1 := Random(sz1); n2 := Random(sz2); sum1 := n1+n2; sum2 := sum1-n2; if Equal(sum2,n1) then put("n1+n2-n2 okay"); else put("n1+n2-n2 Bug!"); Report_Bug; end if; Add(sum2,n2); if Equal(sum2,sum1) then put(" Add okay"); else put(" Add Bug!"); Report_Bug; end if; Sub(sum2,n1); if Equal(sum2,n2) then put(" Sub okay"); new_line; else put(" Sub Bug!"); Report_Bug; end if; Clear(n1); Clear(n2); Clear(sum1); Clear(sum2); end Random_Addition_and_Subtraction; procedure Additions_and_Subtractions_on_Randoms is -- DESCRIPTION : -- Generates a number of random naturals and performs repeated -- additions and subtractions with checks on consistencies. nb,sz1,sz2 : natural; begin put("Give the number of tests : "); get(nb); put("Give the size of the 1st number : "); get(sz1); put("Give the size of the 2nd number : "); get(sz2); for i in 1..nb loop Random_Addition_and_Subtraction(sz1,sz2); end loop; end Additions_and_Subtractions_on_Randoms; procedure Random_Multiplication_and_Division ( sz1,sz2 : in natural ) is -- DESCRIPTION : -- Four tests are performed : -- 1) n1*n2/n2 = n1, with "*" and "/". -- 2) Mul(n1,n2) is the same as n1 := n1*n2 ? -- 3) Div(n1*n2,n1) leads to n2 ? -- 4) n1 = (n1/n2)*n2 + Rmd(n1,n2) ? -- 5) Div(n1,n2,q,r) satisfies n1 = q*n2 + r ? n1,n2,prod1,prod2,quot1,quot2,quot3,rest1,rest2 : Natural_Number; procedure Report_Bug is begin new_line; put(" n1 : "); put(n1); new_line; put(" n2 : "); put(n2); new_line; end Report_Bug; begin n1 := Random(sz1); n2 := Random(sz2); prod1 := n1*n2; quot1 := prod1/n2; if Equal(quot1,n1) then put("n1*n2/n2 okay"); else put("n1*n2/n2 Bug!"); Report_Bug; end if; Mul(quot1,n2); if Equal(prod1,quot1) then put(" Mul okay"); else put(" Mul Bug!"); Report_Bug; end if; Div(prod1,n1); if Equal(prod1,n2) then put(" Div okay"); else put(" Div Bug!"); Report_Bug; end if; rest1 := Rmd(n1,n2); quot2 := n1/n2; prod2 := quot2*n2; Add(prod2,rest1); if Equal(prod2,n1) then put(" Rmd okay"); else put(" Rmd Bug!"); Report_Bug; end if; Div(n1,n2,quot3,rest2); Mul(quot3,n2); Add(quot3,rest2); if Equal(quot3,n1) then put(" Div/Rmd okay"); new_line; else put(" Div/Rmd Bug!"); Report_Bug; end if; Clear(n1); Clear(n2); Clear(prod1); Clear(quot1); Clear(prod2); Clear(quot2); Clear(quot3); Clear(rest1); Clear(rest2); end Random_Multiplication_and_Division; procedure Multiplications_and_Divisions_on_Randoms is -- DESCRIPTION : -- Generates a number of random naturals and performs repeated -- multiplications and divisions with checks on consistencies. nb,sz1,sz2 : natural; begin put("Give the number of tests : "); get(nb); put("Give the size of the 1st number : "); get(sz1); put("Give the size of the 2nd number : "); get(sz2); for i in 1..nb loop Random_Multiplication_and_Division(sz1,sz2); end loop; end Multiplications_and_Divisions_on_Randoms; procedure Main is ans : character; begin new_line; put_line("Interactive testing of multi-precision natural numbers."); loop new_line; put_line("Choose one of the following : "); put_line(" 0. exit program 1. Input/Output 2. Creation "); put_line(" 3. Comparison/Copy 4. Addition 5. Subtraction "); put_line(" 6. Multiplication 7. Exponentiation 8. Division "); put_line(" 9. Addition/subtraction on randomly generated numbers. "); put_line(" A. Multiplication/division/remainder on random numbers. "); put("Type in your choice (0,1,2,3,4,5,6,7,8,9 or A) : "); get(ans); exit when (ans = '0'); new_line; case ans is when '1' => Test_io; when '2' => Test_Creation; when '3' => Test_Comparison; when '4' => Test_Addition; when '5' => Test_Subtraction; when '6' => Test_Multiplication; when '7' => Test_Exponentiation; when '8' => Test_Division; when '9' => Additions_and_Subtractions_on_Randoms; when 'A' => Multiplications_and_Divisions_on_Randoms; when others => null; end case; end loop; end Main; begin Main; end ts_natnum;