Annotation of OpenXM_contrib/PHC/Ada/Math_Lib/Numbers/multprec_integer_numbers.adb, Revision 1.1.1.1
1.1 maekawa 1: with unchecked_deallocation;
2:
3: package body Multprec_Integer_Numbers is
4:
5: -- NOTES ON THE CHOICE OF REPRESENTATION AND IMPLEMENTATION :
6: -- 0) See also the notes in the body of Multprec_Natural_Numbers.
7: -- This package inherits the operations on natural numbers, with
8: -- additionally the tests on signs.
9: -- Integer numbers are in fact signed natural numbers.
10: -- 1) The construction of tagged records was judged not appropriate to
11: -- extend the natural numbers, as this construction only applies to
12: -- records, it would have changed the privacy of the implementation.
13:
14: -- DATA STRUCTURE :
15:
16: type Integer_Number_Rep is record
17: plus : boolean;
18: numb : Natural_Number;
19: end record;
20:
21: procedure free is
22: new unchecked_deallocation(Integer_Number_Rep,Integer_Number);
23:
24: -- CREATORS :
25:
26: function Natural_Create ( n : natural ) return Integer_Number is
27:
28: res : Integer_Number;
29: res_rep : Integer_Number_Rep;
30:
31: begin
32: res_rep.plus := true;
33: res_rep.numb := Create(n);
34: res := new Integer_Number_Rep'(res_rep);
35: return res;
36: end Natural_Create;
37:
38: function Create ( n : Array_of_Naturals ) return Integer_Number is
39:
40: res : Integer_Number;
41: res_rep : Integer_Number_Rep;
42:
43: begin
44: res_rep.plus := true;
45: res_rep.numb := Create(n);
46: res := new Integer_Number_Rep'(res_rep);
47: return res;
48: end Create;
49:
50: function Create ( n : Natural_Number ) return Integer_Number is
51:
52: res : Integer_Number;
53: res_rep : Integer_Number_Rep;
54:
55: begin
56: res_rep.plus := true;
57: res_rep.numb := +n; --Copy(n,res_rep.numb);
58: res := new Integer_Number_Rep'(res_rep);
59: return res;
60: end Create;
61:
62: function Create ( i : integer ) return Integer_Number is
63:
64: res : Integer_Number;
65: n : natural;
66:
67: begin
68: if i >= 0
69: then n := i;
70: res := Natural_Create(n);
71: res.plus := true;
72: else n := -i;
73: res := Natural_Create(n);
74: res.plus := false;
75: end if;
76: return res;
77: end Create;
78:
79: function Convert ( n : Natural_Number ) return Integer_Number is
80:
81: res : Integer_Number;
82: res_rep : Integer_Number_Rep;
83:
84: begin
85: res_rep.numb := n;
86: res_rep.plus := true;
87: res := new Integer_Number_Rep'(res_rep);
88: return res;
89: end Convert;
90:
91: function Create ( i : Integer_Number ) return integer is
92:
93: res : integer;
94: nres : natural;
95:
96: begin
97: if (Empty(i) or else Empty(i.numb))
98: then res := 0;
99: else nres := Create(i.numb);
100: if i.plus
101: then res := nres;
102: else res := -nres;
103: end if;
104: end if;
105: return res;
106: end Create;
107:
108: -- SELECTORS :
109:
110: function Empty ( i : Integer_Number ) return boolean is
111: begin
112: return (i=null);
113: end Empty;
114:
115: function Size ( i : Integer_Number ) return natural is
116: begin
117: if Empty(i)
118: then return 0;
119: else return Size(i.numb);
120: end if;
121: end Size;
122:
123: function Coefficient ( i : Integer_Number; k : natural ) return natural is
124: begin
125: if (Empty(i) or else (k > Size(i)))
126: then return 0;
127: else return Coefficient(i.numb,k);
128: end if;
129: end Coefficient;
130:
131: function Coefficients ( i : Integer_Number ) return Array_of_Naturals is
132:
133: nullres : Array_of_Naturals(0..0) := (0..0 => 0);
134:
135: begin
136: if not Empty(i)
137: then return Coefficients(i.numb);
138: else return nullres;
139: end if;
140: end Coefficients;
141:
142: function Decimal_Places ( i : Integer_Number ) return natural is
143: begin
144: if Empty(i)
145: then return 0;
146: else return Decimal_Places(i.numb);
147: end if;
148: end Decimal_Places;
149:
150: function Positive ( i : Integer_Number ) return boolean is
151: begin
152: if Empty(i)
153: then return false;
154: elsif Empty(i.numb)
155: then return false;
156: -- elsif Equal(i.numb,0) -- whatever sign you wish to give to 0
157: -- then return false; -- convenient to work with for input
158: else return i.plus;
159: end if;
160: end Positive;
161:
162: function Negative ( i : Integer_Number ) return boolean is
163: begin
164: if Empty(i)
165: then return false;
166: elsif Empty(i.numb)
167: then return false;
168: -- elsif Equal(i.numb,0) -- for input of floating-point numbers
169: -- then return false; -- convenient for reading -0.01
170: else return not i.plus;
171: end if;
172: end Negative;
173:
174: function Sign ( i : Integer_Number ) return integer is
175: begin
176: if Empty(i) or Equal(i,0)
177: then return 0;
178: elsif Positive(i)
179: then return +1;
180: else return -1;
181: end if;
182: end Sign;
183:
184: function Unsigned ( i : Integer_Number ) return Natural_Number is
185:
186: res : Natural_Number;
187:
188: begin
189: if not Empty(i)
190: then res := i.numb;
191: end if;
192: return res;
193: end Unsigned;
194:
195: -- COMPARISON AND COPYING :
196:
197: function Equal ( i1 : Integer_Number; i2 : integer ) return boolean is
198: begin
199: if Empty(i1)
200: then return (i2 = 0);
201: elsif ((i1.plus and i2 < 0) or else (not i1.plus and i2 > 0))
202: then return false;
203: elsif Empty(i1.numb)
204: then if i2 = 0
205: then return true;
206: else return false;
207: end if;
208: elsif i2 >= 0
209: then return Equal(i1.numb,i2);
210: else return Equal(i1.numb,-i2);
211: end if;
212: end Equal;
213:
214: function Equal ( i1,i2 : Integer_Number ) return boolean is
215: begin
216: if Empty(i1)
217: then return Equal(i2,0);
218: elsif Empty(i2)
219: then return Equal(i1,0);
220: else if (Positive(i1) and Negative(i2))
221: or else (Negative(i1) and Positive(i2))
222: then return false;
223: else return Equal(i1.numb,i2.numb);
224: end if;
225: end if;
226: end Equal;
227:
228: function "<" ( i1 : Integer_Number; i2 : integer ) return boolean is
229: begin
230: if Empty(i1)
231: then return (i2 > 0);
232: else if Positive(i1)
233: then if i2 <= 0
234: then return false;
235: else return (i1.numb < i2);
236: end if;
237: elsif Negative(i1)
238: then if i2 >= 0
239: then return true;
240: else return (i1.numb > -i2);
241: end if;
242: else return (i2 > 0);
243: end if;
244: end if;
245: end "<";
246:
247: function "<" ( i1 : integer; i2 : Integer_Number ) return boolean is
248: begin
249: if Empty(i2)
250: then return (i1 < 0);
251: else if Positive(i2)
252: then if i1 <= 0
253: then return true;
254: else return (i1 < i2.numb);
255: end if;
256: elsif Negative(i2)
257: then if i1 >= 0
258: then return false;
259: else return (-i1 > i2.numb);
260: end if;
261: else return (i1 < 0);
262: end if;
263: end if;
264: end "<";
265:
266: function "<" ( i1,i2 : Integer_Number ) return boolean is
267: begin
268: if Empty(i1)
269: then return Positive(i2);
270: elsif Empty(i2)
271: then return Negative(i1);
272: elsif Positive(i1)
273: then if Negative(i2)
274: then return false;
275: else return (i1.numb < i2.numb);
276: end if;
277: elsif Negative(i1)
278: then if Positive(i2)
279: then return true;
280: else return (i1.numb > i2.numb);
281: end if;
282: else return Positive(i2);
283: end if;
284: end "<";
285:
286: function ">" ( i1 : Integer_Number; i2 : integer ) return boolean is
287: begin
288: if Empty(i1)
289: then return (i2 < 0);
290: else if Negative(i1)
291: then if i2 >= 0
292: then return false;
293: else return (i1.numb < -i2);
294: end if;
295: elsif Positive(i1)
296: then if i2 <= 0
297: then return true;
298: else return (i1.numb > i2);
299: end if;
300: else return (i2 < 0);
301: end if;
302: end if;
303: end ">";
304:
305: function ">" ( i1 : integer; i2 : Integer_Number ) return boolean is
306: begin
307: if Empty(i2)
308: then return (i1 > 0);
309: else if Positive(i2)
310: then if i1 <= 0
311: then return false;
312: else return (i1 > i2.numb);
313: end if;
314: elsif Negative(i2)
315: then if i1 >= 0
316: then return true;
317: else return (-i1 < i2.numb);
318: end if;
319: else return (i1 > 0);
320: end if;
321: end if;
322: end ">";
323:
324: function ">" ( i1,i2 : Integer_Number ) return boolean is
325: begin
326: if Empty(i1)
327: then return Negative(i2);
328: elsif Empty(i2)
329: then return Positive(i1);
330: elsif Positive(i1)
331: then if Negative(i2)
332: then return true;
333: else return (i1.numb > i2.numb);
334: end if;
335: elsif Negative(i1)
336: then if Positive(i2)
337: then return false;
338: else return (i1.numb < i2.numb);
339: end if;
340: else return Negative(i2);
341: end if;
342: end ">";
343:
344: procedure Copy ( i1 : in integer; i2 : in out Integer_Number ) is
345: begin
346: Clear(i2);
347: i2 := Create(i1);
348: end Copy;
349:
350: procedure Copy ( i1 : in Integer_Number; i2 : in out Integer_Number ) is
351: begin
352: Clear(i2);
353: if not Empty(i1)
354: then declare
355: i2rep : Integer_Number_Rep;
356: begin
357: i2rep.plus := i1.plus;
358: i2rep.numb := +i1.numb;
359: i2 := new Integer_Number_Rep'(i2rep);
360: end;
361: end if;
362: end Copy;
363:
364: -- ARITHMETIC OPERATIONS as functions :
365:
366: function "+" ( i1 : Integer_Number; i2 : integer ) return Integer_Number is
367:
368: res : Integer_Number;
369: res_rep : Integer_Number_Rep;
370: n : natural;
371:
372: begin
373: if (Empty(i1) or else Empty(i1.numb))
374: then res := Create(i2);
375: else if i1.plus
376: then if i2 >= 0
377: then n := i2;
378: res_rep.plus := true;
379: res_rep.numb := i1.numb + n;
380: res := new Integer_Number_Rep'(res_rep);
381: else n := -i2;
382: if not Equal(i1.numb,n)
383: then if i1.numb > n
384: then res_rep.plus := true;
385: res_rep.numb := i1.numb - n;
386: else res_rep.plus := false;
387: res_rep.numb := n - i1.numb;
388: end if;
389: res := new Integer_Number_Rep'(res_rep);
390: end if;
391: end if;
392: else if i2 <= 0
393: then n := -i2;
394: res_rep.plus := false;
395: res_rep.numb := i1.numb + n;
396: res := new Integer_Number_Rep'(res_rep);
397: else n := i2;
398: if not Equal(i1.numb,n)
399: then if i1.numb < n
400: then res_rep.plus := true;
401: res_rep.numb := n - i1.numb;
402: else res_rep.plus := false;
403: res_rep.numb := i1.numb - n;
404: end if;
405: res := new Integer_Number_Rep'(res_rep);
406: end if;
407: end if;
408: end if;
409: end if;
410: return res;
411: end "+";
412:
413: function "+" ( i1 : integer; i2 : Integer_Number ) return Integer_Number is
414: begin
415: return (i2+i1);
416: end "+";
417:
418: function "+" ( i1,i2 : Integer_Number ) return Integer_Number is
419:
420: res : Integer_Number;
421: res_rep : Integer_Number_Rep;
422:
423: begin
424: if (Empty(i1) or else Empty(i1.numb))
425: then Copy(i2,res);
426: else if (Empty(i2) or else Empty(i2.numb))
427: then Copy(i1,res);
428: else if i1.plus
429: then if i2.plus
430: then res_rep.plus := true;
431: res_rep.numb := i1.numb + i2.numb;
432: res := new Integer_Number_Rep'(res_rep);
433: else if not Equal(i1.numb,i2.numb)
434: then if i1.numb > i2.numb
435: then res_rep.plus := true;
436: res_rep.numb := i1.numb - i2.numb;
437: else res_rep.plus := false;
438: res_rep.numb := i2.numb - i1.numb;
439: end if;
440: res := new Integer_Number_Rep'(res_rep);
441: end if;
442: end if;
443: else if not i2.plus
444: then res_rep.plus := false;
445: res_rep.numb := i1.numb + i2.numb;
446: res := new Integer_Number_Rep'(res_rep);
447: else if not Equal(i1.numb,i2.numb)
448: then if i1.numb < i2.numb
449: then res_rep.plus := true;
450: res_rep.numb := i2.numb - i1.numb;
451: else res_rep.plus := false;
452: res_rep.numb := i1.numb - i2.numb;
453: end if;
454: res := new Integer_Number_Rep'(res_rep);
455: end if;
456: end if;
457: end if;
458: end if;
459: end if;
460: return res;
461: end "+";
462:
463: function "+" ( i : Integer_Number ) return Integer_Number is
464:
465: res : Integer_Number;
466:
467: begin
468: Copy(i,res);
469: return res;
470: end "+";
471:
472: function "-" ( i : Integer_Number ) return Integer_Number is
473:
474: res : Integer_Number;
475: res_rep : Integer_Number_Rep;
476:
477: begin
478: if not Empty(i)
479: then res_rep.plus := not i.plus;
480: res_rep.numb := +i.numb; -- Copy(i.numb,res_rep.numb);
481: res := new Integer_Number_Rep'(res_rep);
482: end if;
483: return res;
484: end "-";
485:
486: function "-" ( i1 : Integer_Number; i2 : integer ) return Integer_Number is
487:
488: mini2 : constant integer := -i2;
489:
490: begin
491: return (i1+mini2);
492: end "-";
493:
494: function "-" ( i1 : integer; i2 : Integer_Number ) return Integer_Number is
495:
496: res : Integer_Number := i2 - i1;
497:
498: begin
499: Min(res);
500: return res;
501: end "-";
502:
503: function "-" ( i1,i2 : Integer_Number ) return Integer_Number is
504:
505: res,mini2 : Integer_Number;
506: mini2rep : Integer_Number_Rep;
507:
508: begin
509: if (Empty(i2) or else Empty(i2.numb))
510: then Copy(i1,res);
511: else mini2rep.numb := i2.numb;
512: mini2rep.plus := not i2.plus;
513: mini2 := new Integer_Number_Rep'(mini2rep);
514: res := i1 + mini2;
515: free(mini2);
516: end if;
517: return res;
518: end "-";
519:
520: function "*" ( i1 : Integer_Number; i2 : integer ) return Integer_Number is
521:
522: res : Integer_Number;
523: res_rep : Integer_Number_Rep;
524: n : natural;
525:
526: begin
527: if not ((i2 = 0) or else Empty(i1) or else Empty(i1.numb))
528: then if i2 > 0
529: then n := i2;
530: res_rep.plus := i1.plus;
531: else n := -i2;
532: res_rep.plus := not i1.plus;
533: end if;
534: res_rep.numb := i1.numb*n;
535: res := new Integer_Number_Rep'(res_rep);
536: end if;
537: return res;
538: end "*";
539:
540: function "*" ( i1 : integer; i2 : Integer_Number ) return Integer_Number is
541: begin
542: return (i2*i1);
543: end "*";
544:
545: function "*" ( i1,i2 : Integer_Number ) return Integer_Number is
546:
547: res : Integer_Number;
548: res_rep : Integer_Number_Rep;
549:
550: begin
551: if (not (Empty(i1) or else Empty(i1.numb)))
552: and then (not (Empty(i2) or else Empty(i2.numb)))
553: then res_rep.numb := i1.numb*i2.numb;
554: res_rep.plus := i1.plus;
555: if not i2.plus
556: then res_rep.plus := not res_rep.plus;
557: end if;
558: res := new Integer_Number_Rep'(res_rep);
559: end if;
560: return res;
561: end "*";
562:
563: function "**" ( i : Integer_Number; n : natural ) return Integer_Number is
564:
565: res : Integer_Number;
566: res_rep : Integer_Number_Rep;
567:
568: begin
569: if n = 0
570: then res := Create(1);
571: else if not (Empty(i) or else Empty(i.numb))
572: then res_rep.numb := i.numb**n;
573: res_rep.plus := i.plus;
574: if ((not i.plus) and then (n mod 2 = 1))
575: then res_rep.plus := not res_rep.plus;
576: end if;
577: res := new Integer_Number_Rep'(res_rep);
578: end if;
579: end if;
580: return res;
581: end "**";
582:
583: function "**" ( i : integer; n : Natural_Number ) return Integer_Number is
584:
585: res : Integer_Number;
586: res_rep : Integer_Number_Rep;
587: ni : natural;
588:
589: begin
590: if (Empty(n) or else Equal(n,0))
591: then res := Create(1);
592: else if i /= 0
593: then if i > 0
594: then ni := i;
595: res_rep.plus := true;
596: else ni := -i;
597: res_rep.plus := false;
598: end if;
599: res_rep.numb := ni**n;
600: if (i < 0 and then (Rmd(n,2) = 0))
601: then res_rep.plus := not res_rep.plus;
602: end if;
603: res := new Integer_Number_Rep'(res_rep);
604: end if;
605: end if;
606: return res;
607: end "**";
608:
609: function "**" ( i : Integer_Number; n : Natural_Number )
610: return Integer_Number is
611:
612: res : Integer_Number;
613: res_rep : Integer_Number_Rep;
614:
615: begin
616: if (Empty(n) or else Equal(n,0))
617: then res := Create(1);
618: else if not (Empty(i) or else Empty(i.numb))
619: then res_rep.numb := i.numb**n;
620: res_rep.plus := i.plus;
621: if ((not i.plus) and then (Rmd(n,2) = 0))
622: then res_rep.plus := not res_rep.plus;
623: end if;
624: res := new Integer_Number_Rep'(res_rep);
625: end if;
626: end if;
627: return res;
628: end "**";
629:
630: function "/" ( i1 : Integer_Number; i2 : integer ) return Integer_Number is
631:
632: res : Integer_Number;
633: i2n : natural;
634: res_rep : Integer_Number_Rep;
635:
636: begin
637: if i2 /= 0
638: then if not (Empty(i1) or else Empty(i1.numb))
639: then if i2 > 0
640: then i2n := i2;
641: else i2n := -i2;
642: end if;
643: res_rep.numb := i1.numb/i2n;
644: if (i1.plus and (i2 > 0)) or ((not i1.plus) and (i2 < 0))
645: then res_rep.plus := true;
646: else res_rep.plus := false;
647: end if;
648: res := new Integer_Number_Rep'(res_rep);
649: end if;
650: else raise NUMERIC_ERROR;
651: end if;
652: return res;
653: end "/";
654:
655: function "/" ( i1 : integer; i2 : Integer_Number ) return integer is
656:
657: res : integer;
658: i1n,nres : natural;
659:
660: begin
661: if (Empty(i2) or else Empty(i2.numb))
662: then raise NUMERIC_ERROR;
663: else if i1 > 0
664: then i1n := i1;
665: else i1n := -i1;
666: end if;
667: nres := i1n/i2.numb;
668: if ((i1 > 0) and i2.plus) or ((i1 < 0) and (not i2.plus))
669: then res := nres;
670: else res := -nres;
671: end if;
672: end if;
673: return res;
674: end "/";
675:
676: function "/" ( i1,i2 : Integer_Number ) return Integer_Number is
677:
678: res : Integer_Number;
679: res_rep : Integer_Number_Rep;
680:
681: begin
682: if not (Empty(i1) or else Empty(i1.numb))
683: then if (Empty(i2) or else Empty(i2.numb))
684: then raise NUMERIC_ERROR;
685: else res_rep.numb := i1.numb/i2.numb;
686: if (i1.plus and i2.plus) or ((not i1.plus) and (not i2.plus))
687: then res_rep.plus := true;
688: else res_rep.plus := false;
689: end if;
690: res := new Integer_Number_Rep'(res_rep);
691: end if;
692: end if;
693: return res;
694: end "/";
695:
696: function Rmd ( i1 : Integer_Number; i2 : integer ) return integer is
697:
698: res : integer;
699: i2n,nres : natural;
700:
701: begin
702: if i2 /= 0
703: then if (Empty(i1) or else Empty(i1.numb))
704: then res := 0;
705: else if i2 > 0
706: then i2n := i2;
707: else i2n := -i2;
708: end if;
709: nres := Rmd(i1.numb,i2n);
710: if i1.plus
711: then res := nres;
712: else res := -nres;
713: end if;
714: end if;
715: else raise NUMERIC_ERROR;
716: end if;
717: return res;
718: end Rmd;
719:
720: function Rmd ( i1 : integer; i2 : Integer_Number ) return integer is
721:
722: res : integer;
723: i1n,nres : natural;
724:
725: begin
726: if i1 = 0
727: then res := 0;
728: else if (Empty(i2) or else Empty(i2.numb))
729: then raise NUMERIC_ERROR;
730: else if i1 > 0
731: then i1n := i1;
732: else i1n := -i1;
733: end if;
734: nres := Rmd(i1n,i2.numb);
735: if i1 > 0
736: then res := nres;
737: else res := -nres;
738: end if;
739: end if;
740: end if;
741: return res;
742: end Rmd;
743:
744: function Rmd ( i1,i2 : Integer_Number ) return Integer_Number is
745:
746: res : Integer_Number;
747: res_rep : Integer_Number_Rep;
748:
749: begin
750: if not (Empty(i1) or else Empty(i1.numb))
751: then if (Empty(i2) or else Empty(i2.numb))
752: then raise NUMERIC_ERROR;
753: else res_rep.numb := Rmd(i1.numb,i2.numb);
754: res_rep.plus := i1.plus;
755: res := new Integer_Number_Rep'(res_rep);
756: end if;
757: end if;
758: return res;
759: end Rmd;
760:
761: -- ARITHMETIC OPERATIONS as procedures for memory management :
762:
763: procedure Add ( i1 : in out Integer_Number; i2 : in integer ) is
764:
765: n : natural;
766: nn : Natural_Number;
767:
768: begin
769: if (Empty(i1) or else Empty(i1.numb))
770: then i1 := Create(i2);
771: else if i1.plus
772: then if i2 >= 0
773: then n := i2;
774: Add(i1.numb,n);
775: else n := -i2;
776: if not Equal(i1.numb,n)
777: then if i1.numb > n
778: then Sub(i1.numb,n);
779: else i1.plus := false;
780: nn := Create(n);
781: Sub(nn,i1.numb);
782: Clear(i1.numb); i1.numb := nn;
783: end if;
784: else Clear(i1);
785: end if;
786: end if;
787: else if i2 <= 0
788: then n := -i2;
789: Add(i1.numb,n);
790: else n := i2;
791: if not Equal(i1.numb,n)
792: then if i1.numb < n
793: then i1.plus := true;
794: nn := Create(n);
795: Sub(nn,i1.numb);
796: Clear(i1.numb); i1.numb := nn;
797: else Sub(i1.numb,n);
798: end if;
799: else Clear(i1);
800: end if;
801: end if;
802: end if;
803: end if;
804: end Add;
805:
806: procedure Add ( i1 : in out Integer_Number; i2 : in Integer_Number ) is
807:
808: nn : Natural_Number;
809:
810: begin
811: if (Empty(i1) or else Empty(i1.numb))
812: then Copy(i2,i1);
813: else if not (Empty(i2) or else Empty(i2.numb))
814: then if i1.plus
815: then if i2.plus
816: then Add(i1.numb,i2.numb);
817: else if not Equal(i1.numb,i2.numb)
818: then if i1.numb > i2.numb
819: then Sub(i1.numb,i2.numb);
820: else Copy(i2.numb,nn);
821: Sub(nn,i1.numb);
822: Clear(i1.numb);
823: i1.plus := false;
824: i1.numb := nn;
825: end if;
826: else Clear(i1);
827: end if;
828: end if;
829: else if not i2.plus
830: then Add(i1.numb,i2.numb);
831: else if not Equal(i1.numb,i2.numb)
832: then if i1.numb < i2.numb
833: then Copy(i2.numb,nn);
834: Sub(nn,i1.numb);
835: Clear(i1.numb);
836: i1.plus := true;
837: i1.numb := nn;
838: else Sub(i1.numb,i2.numb);
839: end if;
840: else Clear(i1);
841: end if;
842: end if;
843: end if;
844: end if;
845: end if;
846: end Add;
847:
848: procedure Min ( i : in out Integer_Number ) is
849: begin
850: if not Empty(i)
851: then i.plus := not i.plus;
852: end if;
853: end Min;
854:
855: procedure Sub ( i1 : in out Integer_Number; i2 : in integer ) is
856: begin
857: Add(i1,-i2);
858: end Sub;
859:
860: procedure Sub ( i1 : in out Integer_Number; i2 : in Integer_Number ) is
861:
862: mini2 : Integer_Number;
863: mini2rep : Integer_Number_Rep;
864:
865: begin
866: if not (Empty(i2) or else Empty(i2.numb))
867: then mini2rep.numb := i2.numb;
868: mini2rep.plus := not i2.plus;
869: mini2 := new Integer_Number_Rep'(mini2rep);
870: Add(i1,mini2);
871: free(mini2);
872: end if;
873: end Sub;
874:
875: procedure Mul ( i1 : in out Integer_Number; i2 : in integer ) is
876:
877: n : natural;
878:
879: begin
880: if not (Empty(i1) or else Empty(i1.numb))
881: then if i2 = 0
882: then Clear(i1);
883: else if i2 > 0
884: then n := i2;
885: else n := -i2;
886: i1.plus := not i1.plus;
887: end if;
888: Mul(i1.numb,n);
889: end if;
890: end if;
891: end Mul;
892:
893: procedure Mul ( i1 : in out Integer_Number; i2 : in Integer_Number ) is
894: begin
895: if (not (Empty(i1) or else Empty(i1.numb)))
896: then if (Empty(i2) or else Empty(i2.numb))
897: then Clear(i1);
898: else Mul(i1.numb,i2.numb);
899: if not i2.plus
900: then i1.plus := not i1.plus;
901: end if;
902: end if;
903: end if;
904: end Mul;
905:
906: procedure Rmd ( i1 : in out Integer_Number; i2 : in integer ) is
907:
908: res : Integer_Number := Create(Rmd(i1,i2));
909:
910: begin
911: Clear(i1); i1 := res;
912: end Rmd;
913:
914: procedure Rmd ( i1 : in out Integer_Number; i2 : in Integer_Number ) is
915:
916: res : Integer_Number := Rmd(i1,i2);
917:
918: begin
919: Clear(i1); i1 := res;
920: end Rmd;
921:
922: procedure Div ( i1 : in out Integer_Number; i2 : in integer ) is
923:
924: r : integer;
925:
926: begin
927: Div(i1,i2,r);
928: end Div;
929:
930: procedure Div ( i1 : in out Integer_Number; i2 : in Integer_Number ) is
931:
932: r : Integer_Number;
933:
934: begin
935: Div(i1,i2,r);
936: Clear(r);
937: end Div;
938:
939: procedure Div ( i1 : in Integer_Number; i2 : in integer;
940: q : out Integer_Number; r : out integer ) is
941:
942: qrep : Integer_Number_Rep;
943: i2n,rn : natural;
944:
945: begin
946: if i2 /= 0
947: then if not (Empty(i1) or else Empty(i1.numb))
948: then if i2 > 0
949: then i2n := i2;
950: else i2n := -i2;
951: end if;
952: Div(i1.numb,i2n,qrep.numb,rn);
953: if (i1.plus and (i2 > 0)) or ((not i1.plus) and (i2 < 0))
954: then qrep.plus := true;
955: else qrep.plus := false;
956: end if;
957: q := new Integer_Number_Rep'(qrep);
958: if i1.plus
959: then r := rn;
960: else r := -rn;
961: end if;
962: end if;
963: else raise NUMERIC_ERROR;
964: end if;
965: end Div;
966:
967: procedure Div ( i1 : in out Integer_Number; i2 : in integer;
968: r : out integer ) is
969:
970: i2n,rn : natural;
971:
972: begin
973: if i2 /= 0
974: then if not (Empty(i1) or else Empty(i1.numb))
975: then if i2 > 0
976: then i2n := i2;
977: else i2n := -i2;
978: end if;
979: Div(i1.numb,i2n,rn);
980: if i1.plus
981: then r := rn;
982: else r := -rn;
983: end if;
984: if (i1.plus and (i2 > 0)) or ((not i1.plus) and (i2 < 0))
985: then i1.plus := true;
986: else i1.plus := false;
987: end if;
988: end if;
989: else raise NUMERIC_ERROR;
990: end if;
991: end Div;
992:
993: procedure Div ( i1,i2 : in Integer_Number; q,r : out Integer_Number ) is
994:
995: qrep,rrep : Integer_Number_Rep;
996:
997: begin
998: if not (Empty(i2) or else Empty(i2.numb))
999: then if not (Empty(i1) or else Empty(i1.numb))
1000: then Div(i1.numb,i2.numb,qrep.numb,rrep.numb);
1001: if (i1.plus and (i2 > 0)) or ((not i1.plus) and (i2 < 0))
1002: then qrep.plus := true;
1003: else qrep.plus := false;
1004: end if;
1005: q := new Integer_Number_Rep'(qrep);
1006: rrep.plus := i1.plus;
1007: r := new Integer_Number_Rep'(rrep);
1008: end if;
1009: else raise NUMERIC_ERROR;
1010: end if;
1011: end Div;
1012:
1013: procedure Div ( i1 : in out Integer_Number; i2 : in Integer_Number;
1014: r : out Integer_Number ) is
1015:
1016: rrep : Integer_Number_Rep;
1017:
1018: begin
1019: if not (Empty(i2) or else Empty(i2.numb))
1020: then if not (Empty(i1) or else Empty(i1.numb))
1021: then Div(i1.numb,i2.numb,rrep.numb);
1022: rrep.plus := i1.plus;
1023: r := new Integer_Number_Rep'(rrep);
1024: if (i1.plus and (i2 > 0)) or ((not i1.plus) and (i2 < 0))
1025: then i1.plus := true;
1026: else i1.plus := false;
1027: end if;
1028: end if;
1029: else raise NUMERIC_ERROR;
1030: end if;
1031: end Div;
1032:
1033: -- DESTRUCTOR :
1034:
1035: procedure Clear ( i : in out Integer_Number ) is
1036: begin
1037: if not Empty(i)
1038: then Clear(i.numb);
1039: free(i);
1040: i := null;
1041: end if;
1042: end Clear;
1043:
1044: end Multprec_Integer_Numbers;
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>