[BACK]Return to ts_natnum.adb CVS log [TXT][DIR] Up to [local] / OpenXM_contrib / PHC / Ada / Math_Lib / Numbers

Annotation of OpenXM_contrib/PHC/Ada/Math_Lib/Numbers/ts_natnum.adb, Revision 1.1.1.1

1.1       maekawa     1: with text_io,integer_io;                 use text_io,integer_io;
                      2: with Multprec_Natural_Numbers;           use Multprec_Natural_Numbers;
                      3: with Multprec_Natural_Numbers_io;        use Multprec_Natural_Numbers_io;
                      4: with Multprec_Random_Numbers;            use Multprec_Random_Numbers;
                      5:
                      6: procedure ts_natnum is
                      7:
                      8: -- DESCRIPTION :
                      9: --   This procedure offers interactive and random testers for the
                     10: --   operations with multi-precision natural numbers.  See the menu below.
                     11:
                     12:   procedure Test_Creation is
                     13:
                     14:     n : natural;
                     15:     nn : Natural_Number;
                     16:     ans : character;
                     17:
                     18:   begin
                     19:     put_line("Testing the creation of a natural number.");
                     20:     loop
                     21:       put("Give a standard natural number : "); get(n);
                     22:       nn := Create(n);
                     23:       put("-> as natural number : "); put(nn); new_line;
                     24:       Clear(nn);
                     25:       put("Do you want more tests ? (y/n) "); get(ans);
                     26:       exit when ans /= 'y';
                     27:     end loop;
                     28:   end Test_Creation;
                     29:
                     30:   procedure Test_io is
                     31:
                     32:     ans : character;
                     33:     n : Natural_Number;
                     34:
                     35:   begin
                     36:     put_line("Testing the input/output operations.");
                     37:     loop
                     38:       put("Give a number : "); get(n);
                     39:       put("-> your number : "); put(n); new_line;
                     40:       put("#decimal places : "); put(Decimal_Places(n),1); new_line;
                     41:       put("Do you want more tests ? (y/n) "); get(ans);
                     42:       exit when ans /= 'y';
                     43:     end loop;
                     44:   end Test_io;
                     45:
                     46:   procedure Test_Compare ( n1 : in Natural_Number; n2 : in natural ) is
                     47:   begin
                     48:     if Equal(n1,n2)
                     49:      then put_line("The numbers are equal.");
                     50:      else put_line("The numbers are different.");
                     51:     end if;
                     52:     if n1 < n2
                     53:      then put_line("First is less than second.");
                     54:      else put_line("First not less than second.");
                     55:     end if;
                     56:     if n1 > n2
                     57:      then put_line("First is greater than second.");
                     58:      else put_line("First is not greater than second.");
                     59:     end if;
                     60:   end Test_Compare;
                     61:
                     62:   procedure Test_Compare ( n1 : in natural; n2 : in Natural_Number ) is
                     63:   begin
                     64:     if Equal(n2,n1)
                     65:      then put_line("Both numbers are equal.");
                     66:      else put_line("The numbers are different.");
                     67:     end if;
                     68:     if n1 < n2
                     69:      then put_line("First is less than second.");
                     70:      else put_line("First not less than second.");
                     71:     end if;
                     72:     if n1 > n2
                     73:      then put_line("First is greater than second.");
                     74:      else put_line("First is not greater than second.");
                     75:     end if;
                     76:   end Test_Compare;
                     77:
                     78:   procedure Test_Compare ( n1,n2 : in Natural_Number ) is
                     79:   begin
                     80:     if Equal(n1,n2)
                     81:      then put_line("Both numbers are equal.");
                     82:      else put_line("The numbers are different.");
                     83:     end if;
                     84:     if n1 < n2
                     85:      then put_line("First is less than second.");
                     86:      else put_line("First not less than second.");
                     87:     end if;
                     88:     if n1 > n2
                     89:      then put_line("First is greater than second.");
                     90:      else put_line("First is not greater than second.");
                     91:     end if;
                     92:   end Test_Compare;
                     93:
                     94:   procedure Test_Comparison is
                     95:
                     96:     ans : character;
                     97:     n1,n2 : Natural_Number;
                     98:    -- n1 : natural;
                     99:
                    100:   begin
                    101:     put_line("Testing the comparison operations.");
                    102:     loop
                    103:       put("Give 1st number n1 : "); get(n1);
                    104:       put("-> n1 : "); put(n1); new_line;
                    105:       put("Give 2nd number n2 : "); get(n2);
                    106:       put("-> n2 : "); put(n2); new_line;
                    107:       Test_Compare(n1,n2);
                    108:       Copy(n1,n2);
                    109:       put_line("Tests after copying : ");
                    110:       Test_Compare(n1,n2);
                    111:       Div(n1,10);
                    112:       put_line("After dividing n1 by 10 :");
                    113:       put(" n1 : "); put(n1); new_line;
                    114:       put(" n2 : "); put(n2); new_line;
                    115:       put("Do you want more tests ? (y/n) "); get(ans);
                    116:       exit when ans /= 'y';
                    117:     end loop;
                    118:   end Test_Comparison;
                    119:
                    120:   procedure Test_Addition is
                    121:
                    122:   -- NOTE : to test n1+n2 with n2 a standard natural,
                    123:   --        just change the declaration of n2.
                    124:
                    125:     ans : character;
                    126:     n1,n2,sum1,sum2 : Natural_Number;
                    127:
                    128:   begin
                    129:     put_line("Testing the addition operations.");
                    130:     loop
                    131:       put("Give 1st number : "); get(n1);
                    132:       put("-> your 1st number n1 : "); put(n1); new_line;
                    133:       put("Give 2nd number : "); get(n2);
                    134:       put("-> your 2nd number n2 : "); put(n2); new_line;
                    135:       sum1 := n1+n2;
                    136:       put("n1+n2 : "); put(sum1); new_line;
                    137:       sum2 := n2+n1;
                    138:       put("n2+n1 : "); put(sum2); new_line;
                    139:       if Equal(sum1,sum2)
                    140:        then put_line("Test on commutativity is successful.");
                    141:        else put_line("Failure, sum not commutative: bug!");
                    142:       end if;
                    143:       put("Do you want more tests ? (y/n) "); get(ans);
                    144:       exit when ans /= 'y';
                    145:     end loop;
                    146:   end Test_Addition;
                    147:
                    148:   function Mult_by_Add ( n1 : Natural_Number; n2 : natural )
                    149:                        return Natural_Number is
                    150:
                    151:
                    152:   -- DESCRIPTION :
                    153:   --   Does the multiplication by adding up n1 to itself as many times
                    154:   --   as the number n2.  Only to be used as test of course.
                    155:
                    156:     res : Natural_Number;
                    157:
                    158:   begin
                    159:     if n2 = 0
                    160:      then return res;
                    161:      else Copy(n1,res);
                    162:           for i in 1..n2-1 loop
                    163:             Add(res,n1);
                    164:           end loop;
                    165:           return res;
                    166:     end if;
                    167:   end Mult_by_Add;
                    168:
                    169:   function Mult_by_Add ( n1,n2 : Natural_Number ) return Natural_Number is
                    170:
                    171:
                    172:   -- DESCRIPTION :
                    173:   --   Does the multiplication by adding up n1 to itself as many times
                    174:   --   as the number n2.  Only to be used as test of course.
                    175:   --   This can be quite time consuming as n2 gets large.
                    176:
                    177:     res,cnt : Natural_Number;
                    178:
                    179:   begin
                    180:     if Equal(n2,0)
                    181:      then return res;
                    182:      else Copy(n1,res);
                    183:           cnt := Create(1);
                    184:           while not Equal(cnt,n2) loop
                    185:             Add(res,n1);
                    186:             Add(cnt,1);
                    187:           end loop;
                    188:           Clear(cnt);
                    189:           return res;
                    190:     end if;
                    191:   end Mult_by_Add;
                    192:
                    193:   procedure Test_Multiplication is
                    194:
                    195:   -- NOTE : to test n1*n2 with n2 : natural, change the declaration of n2.
                    196:
                    197:     ans : character;
                    198:     n1,prod1,prod2,prod3 : Natural_Number;
                    199:     n2 : natural;
                    200:
                    201:   begin
                    202:     put_line("Testing the multiplication operations.");
                    203:     loop
                    204:       put("Give 1st number : "); get(n1);
                    205:       put("-> your 1st number : "); put(n1); new_line;
                    206:       put("Give 2nd number : "); get(n2);
                    207:       put("-> your 2nd number : "); put(n2); new_line;
                    208:       prod1 := n1*n2;
                    209:       put("Product n1*n2 : "); put(prod1); new_line;
                    210:       prod2 := n2*n1;
                    211:       put("Product n2*n1 : "); put(prod2); new_line;
                    212:       if Equal(prod1,prod2)
                    213:        then put_line("Test on commutativity is successful.");
                    214:        else put_line("Failure, product not commutative: bug!");
                    215:       end if;
                    216:       put("Do you want multiplication by addition ? (y/n) "); get(ans);
                    217:       if ans = 'y'
                    218:        then put_line("Testing the multiplication by addition.  Be patient...");
                    219:             prod3 := Mult_by_Add(n1,n2);
                    220:             put("After adding "); put(n2); put(" times : "); put(prod3);
                    221:             new_line;
                    222:             if Equal(prod1,prod3)
                    223:              then put_line("Test of multiplication is successful.");
                    224:              else put_line("Failure, bug detected.");
                    225:             end if;
                    226:       end if;
                    227:       put("Do you want more tests ? (y/n) "); get(ans);
                    228:       exit when ans /= 'y';
                    229:     end loop;
                    230:   end Test_Multiplication;
                    231:
                    232:   procedure Test_Exponentiation is
                    233:
                    234:     ans : character;
                    235:     n,e1,e2,exp1,exp2,prod,expo : Natural_Number;
                    236:
                    237:   begin
                    238:     put_line("Testing the exponentiation operations.");
                    239:     loop
                    240:       put("Give a number : "); get(n);
                    241:       put("-> your number n : "); put(n); new_line;
                    242:       put("Give 1st exponent : "); get(e1);
                    243:       put("-> your 1st exponent e1 : "); put(e1); new_line;
                    244:       exp1 := n**e1;
                    245:       put("n**e1 : "); put(exp1); new_line;
                    246:       put("Give 2nd exponent : "); get(e2);
                    247:       put("-> your 2nd exponent e2 : "); put(e2); new_line;
                    248:       exp2 := n**e2;
                    249:       put("n**e2 : "); put(exp2); new_line;
                    250:       prod := exp1*exp2;
                    251:       put("(n**e1)*(n**e2) : "); put(prod); new_line;
                    252:       expo := n**(e1+e2);
                    253:       put("n**(e1+e2)      : "); put(expo); new_line;
                    254:       if Equal(prod,expo)
                    255:        then put_line("Test of exponentiation is successful.");
                    256:        else put_line("Failure, bug detected.");
                    257:       end if;
                    258:       put("Do you want more tests ? (y/n) "); get(ans);
                    259:       exit when ans /= 'y';
                    260:     end loop;
                    261:   end Test_Exponentiation;
                    262:
                    263:   procedure Test_Subtraction is
                    264:
                    265:     ans : character;
                    266:     n1,n2,diff : Natural_Number;
                    267:
                    268:   begin
                    269:     put_line("Testing the subtraction operations.");
                    270:     loop
                    271:       put("Give 1st number : "); get(n1);
                    272:       put("-> your 1st number n1 : "); put(n1); new_line;
                    273:       put("Give 2nd number : "); get(n2);
                    274:       put("-> your 2nd number n2 : "); put(n2); new_line;
                    275:       diff := n1-n2;
                    276:       put("n1 - n2 : "); put(diff); new_line;
                    277:       Add(diff,n2);
                    278:       put("(n1-n2)+n2 : "); put(diff); new_line;
                    279:       if Equal(diff,n1)
                    280:        then put_line("Test of subtraction is successful.");
                    281:        else put_line("Failure, bug detected.");
                    282:       end if;
                    283:       put("Do you want more tests ? (y/n) "); get(ans);
                    284:       exit when ans /= 'y';
                    285:     end loop;
                    286:   end Test_Subtraction;
                    287:
                    288:   procedure Divide10 ( n : in Natural_Number ) is
                    289:
                    290:   -- DESCRIPTION :
                    291:   --   Checks whether the number n is divisible by 1..10.
                    292:
                    293:     quot,prod : Natural_Number;
                    294:     rest : natural;
                    295:
                    296:   begin
                    297:     put("n : "); put(n); new_line;
                    298:     for i in 1..10 loop
                    299:       rest := Rmd(n,i);
                    300:       quot := n/i;
                    301:       if rest = 0
                    302:        then put("Divisible by "); put(i,1);
                    303:        else put("Not divisible by "); put(i,1);
                    304:       end if;
                    305:       put("  rest : "); put(rest,1); new_line;
                    306:       put("quotient : "); put(quot); new_line;
                    307:       prod := quot*i + rest;
                    308:       if Equal(prod,n)
                    309:        then put_line("Test on Remainder/Division is successful.");
                    310:        else put_line("Failure, bug detected.");
                    311:       end if;
                    312:     end loop;
                    313:   end Divide10;
                    314:
                    315:   procedure Test_Division is
                    316:
                    317:     ans : character;
                    318:     n1,n2,quot,prod,rest : Natural_Number;
                    319:    -- n2,rest : natural;
                    320:
                    321:   begin
                    322:     put_line("Testing the division operations.");
                    323:     loop
                    324:       put("Give 1st number : "); get(n1);
                    325:       put("-> your 1st number n1 : "); put(n1); new_line;
                    326:       put("Give 2nd number : "); get(n2);
                    327:       put("-> your 2nd number n2 : "); put(n2); new_line;
                    328:       prod := n1*n2;
                    329:       put("n1*n2 : "); put(prod); new_line;
                    330:       quot := prod/n2; rest := Rmd(prod,n2);
                    331:       put("(n1*n2)/n2 : "); put(quot); new_line;
                    332:       put("Remainder : "); put(rest); new_line;
                    333:       if Equal(quot,n1) and Equal(rest,0)
                    334:        then put_line("Test of division is successful.");
                    335:        else put_line("Failure, bug detected.");
                    336:       end if;
                    337:       Div(n1,n2,quot,rest);
                    338:       put("n1/n2 : "); put(quot); new_line;
                    339:       put("rest : "); put(rest); new_line;
                    340:       prod := quot*n2 + rest;
                    341:       if Equal(prod,n1)
                    342:        then put_line("Test of division/remainder computation is successful.");
                    343:        else put_line("Failure, bug detected.");
                    344:       end if;
                    345:      -- if n2 <= 10
                    346:      --  then Divide10(n1);
                    347:      -- end if;
                    348:       put("Do you want more tests ? (y/n) "); get(ans);
                    349:       exit when ans /= 'y';
                    350:     end loop;
                    351:   end Test_Division;
                    352:
                    353:   procedure Random_Addition_and_Subtraction ( sz1,sz2 : in natural ) is
                    354:
                    355:   -- DESCRIPTION :
                    356:   --   Three tests are performed:
                    357:   --   1) n1+n2-n2 = n1, with "+" and "-".
                    358:   --   2) Add(n1,n2) is the same as n1 := n1+n2?
                    359:   --   3) Sub(n1+n2,n1) leads to n2?
                    360:
                    361:     n1,n2,sum1,sum2 : Natural_Number;
                    362:
                    363:     procedure Report_Bug is
                    364:     begin
                    365:       new_line;
                    366:       put("  n1 : "); put(n1); new_line;
                    367:       put("  n2 : "); put(n2); new_line;
                    368:     end Report_Bug;
                    369:
                    370:   begin
                    371:     n1 := Random(sz1);
                    372:     n2 := Random(sz2);
                    373:     sum1 := n1+n2;
                    374:     sum2 := sum1-n2;
                    375:     if Equal(sum2,n1)
                    376:      then put("n1+n2-n2 okay");
                    377:      else put("n1+n2-n2 Bug!"); Report_Bug;
                    378:     end if;
                    379:     Add(sum2,n2);
                    380:     if Equal(sum2,sum1)
                    381:      then put("  Add okay");
                    382:      else put("  Add Bug!"); Report_Bug;
                    383:     end if;
                    384:     Sub(sum2,n1);
                    385:     if Equal(sum2,n2)
                    386:      then put("  Sub okay"); new_line;
                    387:      else put("  Sub Bug!"); Report_Bug;
                    388:     end if;
                    389:     Clear(n1); Clear(n2);
                    390:     Clear(sum1); Clear(sum2);
                    391:   end Random_Addition_and_Subtraction;
                    392:
                    393:   procedure Additions_and_Subtractions_on_Randoms is
                    394:
                    395:   -- DESCRIPTION :
                    396:   --   Generates a number of random naturals and performs repeated
                    397:   --   additions and subtractions with checks on consistencies.
                    398:
                    399:     nb,sz1,sz2 : natural;
                    400:
                    401:   begin
                    402:     put("Give the number of tests : "); get(nb);
                    403:     put("Give the size of the 1st number : "); get(sz1);
                    404:     put("Give the size of the 2nd number : "); get(sz2);
                    405:     for i in 1..nb loop
                    406:       Random_Addition_and_Subtraction(sz1,sz2);
                    407:     end loop;
                    408:   end Additions_and_Subtractions_on_Randoms;
                    409:
                    410:   procedure Random_Multiplication_and_Division ( sz1,sz2 : in natural ) is
                    411:
                    412:   -- DESCRIPTION :
                    413:   --   Four tests are performed :
                    414:   --   1) n1*n2/n2 = n1, with "*" and "/".
                    415:   --   2) Mul(n1,n2) is the same as n1 := n1*n2 ?
                    416:   --   3) Div(n1*n2,n1) leads to n2 ?
                    417:   --   4) n1 = (n1/n2)*n2 + Rmd(n1,n2) ?
                    418:   --   5) Div(n1,n2,q,r) satisfies n1 = q*n2 + r ?
                    419:
                    420:     n1,n2,prod1,prod2,quot1,quot2,quot3,rest1,rest2 : Natural_Number;
                    421:
                    422:     procedure Report_Bug is
                    423:     begin
                    424:       new_line;
                    425:       put("  n1 : "); put(n1); new_line;
                    426:       put("  n2 : "); put(n2); new_line;
                    427:     end Report_Bug;
                    428:
                    429:   begin
                    430:     n1 := Random(sz1);
                    431:     n2 := Random(sz2);
                    432:     prod1 := n1*n2;
                    433:     quot1 := prod1/n2;
                    434:     if Equal(quot1,n1)
                    435:      then put("n1*n2/n2 okay");
                    436:      else put("n1*n2/n2 Bug!"); Report_Bug;
                    437:     end if;
                    438:     Mul(quot1,n2);
                    439:     if Equal(prod1,quot1)
                    440:      then put("  Mul okay");
                    441:      else put("  Mul Bug!"); Report_Bug;
                    442:     end if;
                    443:     Div(prod1,n1);
                    444:     if Equal(prod1,n2)
                    445:      then put("  Div okay");
                    446:      else put("  Div Bug!"); Report_Bug;
                    447:     end if;
                    448:     rest1 := Rmd(n1,n2);
                    449:     quot2 := n1/n2;
                    450:     prod2 := quot2*n2;
                    451:     Add(prod2,rest1);
                    452:     if Equal(prod2,n1)
                    453:      then put("  Rmd okay");
                    454:      else put("  Rmd Bug!"); Report_Bug;
                    455:     end if;
                    456:     Div(n1,n2,quot3,rest2);
                    457:     Mul(quot3,n2);
                    458:     Add(quot3,rest2);
                    459:     if Equal(quot3,n1)
                    460:      then put("  Div/Rmd okay"); new_line;
                    461:      else put("  Div/Rmd Bug!"); Report_Bug;
                    462:     end if;
                    463:     Clear(n1);    Clear(n2);
                    464:     Clear(prod1); Clear(quot1);
                    465:     Clear(prod2); Clear(quot2);
                    466:     Clear(quot3); Clear(rest1); Clear(rest2);
                    467:   end Random_Multiplication_and_Division;
                    468:
                    469:   procedure Multiplications_and_Divisions_on_Randoms is
                    470:
                    471:   -- DESCRIPTION :
                    472:   --   Generates a number of random naturals and performs repeated
                    473:   --   multiplications and divisions with checks on consistencies.
                    474:
                    475:     nb,sz1,sz2 : natural;
                    476:
                    477:   begin
                    478:     put("Give the number of tests : "); get(nb);
                    479:     put("Give the size of the 1st number : "); get(sz1);
                    480:     put("Give the size of the 2nd number : "); get(sz2);
                    481:     for i in 1..nb loop
                    482:       Random_Multiplication_and_Division(sz1,sz2);
                    483:     end loop;
                    484:   end Multiplications_and_Divisions_on_Randoms;
                    485:
                    486:   procedure Main is
                    487:
                    488:     ans : character;
                    489:
                    490:   begin
                    491:     new_line;
                    492:     put_line("Interactive testing of multi-precision natural numbers.");
                    493:     loop
                    494:       new_line;
                    495:       put_line("Choose one of the following : ");
                    496:       put_line("  0. exit program      1. Input/Output     2. Creation      ");
                    497:       put_line("  3. Comparison/Copy   4. Addition         5. Subtraction   ");
                    498:       put_line("  6. Multiplication    7. Exponentiation   8. Division      ");
                    499:       put_line("  9. Addition/subtraction on randomly generated numbers.    ");
                    500:       put_line("  A. Multiplication/division/remainder on random numbers.   ");
                    501:       put("Type in your choice (0,1,2,3,4,5,6,7,8,9 or A) : "); get(ans);
                    502:       exit when (ans = '0');
                    503:       new_line;
                    504:       case ans is
                    505:         when '1' => Test_io;
                    506:         when '2' => Test_Creation;
                    507:         when '3' => Test_Comparison;
                    508:         when '4' => Test_Addition;
                    509:         when '5' => Test_Subtraction;
                    510:         when '6' => Test_Multiplication;
                    511:         when '7' => Test_Exponentiation;
                    512:         when '8' => Test_Division;
                    513:         when '9' => Additions_and_Subtractions_on_Randoms;
                    514:         when 'A' => Multiplications_and_Divisions_on_Randoms;
                    515:         when others => null;
                    516:       end case;
                    517:     end loop;
                    518:   end Main;
                    519:
                    520: begin
                    521:   Main;
                    522: end ts_natnum;

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>