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