1 //   Copyright (c)  2003-2011  John Abbott
2 
3 //   This file is part of the source of CoCoALib, the CoCoA Library.
4 
5 //   CoCoALib is free software: you can redistribute it and/or modify
6 //   it under the terms of the GNU General Public License as published by
7 //   the Free Software Foundation, either version 3 of the License, or
8 //   (at your option) any later version.
9 
10 //   CoCoALib is distributed in the hope that it will be useful,
11 //   but WITHOUT ANY WARRANTY; without even the implied warranty of
12 //   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 //   GNU General Public License for more details.
14 
15 //   You should have received a copy of the GNU General Public License
16 //   along with CoCoALib.  If not, see <http://www.gnu.org/licenses/>.
17 
18 #include "CoCoA/BigInt.H"
19 
20 #include "CoCoA/BigIntOps.H"
21 #include "CoCoA/OpenMath.H"
22 #include "CoCoA/error.H"
23 
24 
25 #include <iostream>
26 using std::ostream;
27 using std::istream;
28 using std::ios;
29 
30 #include <string>
31 using std::string;
32 
33 #include <vector>
34 using std::vector;
35 
36 namespace CoCoA
37 {
38 
BigInt()39   BigInt::BigInt()
40   {
41     mpz_init(myRepr);
42   }
43 
44 
BigInt(const MachineInt & n)45   BigInt::BigInt(const MachineInt& n)
46   {
47     if (IsNegative(n))
48       mpz_init_set_si(myRepr, AsSignedLong(n));
49     else
50       mpz_init_set_ui(myRepr, AsUnsignedLong(n));
51   }
52 
53 
BigInt(const std::string & str,ReadFromString_t)54   BigInt::BigInt(const std::string& str, ReadFromString_t /*NotUsed*/)
55   {
56     mpz_init(myRepr);
57 //     if (base != 0 && (base < 2 || base > 36))
58 //       CoCoA_ERROR(ERR::BadNumBase, "BigInt(string)");
59     if (mpz_set_str(myRepr, str.c_str(), 10) != 0)
60       CoCoA_ERROR(ERR::BadArg, "BigIntFromString");
61   }
62 
63 
BigInt(const mpz_t N,CopyFromMPZ_t)64   BigInt::BigInt(const mpz_t N, CopyFromMPZ_t /* NotUsed*/)
65   {
66     if (N == nullptr)
67       CoCoA_ERROR(ERR::NullPtr, "BigIntFromMPZ");
68 
69     mpz_init_set(myRepr, N);
70   }
71 
72 
73 // COPY CONSTRUCTOR
74 
BigInt(const BigInt & from)75   BigInt::BigInt(const BigInt& from)
76   {
77     mpz_init_set(myRepr, from.myRepr);
78   }
79 
80 
81   BigInt& BigInt::operator=(const BigInt& rhs)
82   {
83     if (this == &rhs) return *this;
84     mpz_set(myRepr, rhs.myRepr);
85     return *this;
86   }
87 
88 
89 
90   // BUG/SLUG slow and wastes space -- better to use ostringstream?
ConvertToString(const BigInt & src,int base)91   std::string ConvertToString(const BigInt& src, int base)
92   {
93     if (base < 2 || base > 36)
94       CoCoA_ERROR(ERR::BadNumBase, "ConvertToString(BigInt,int)");
95     const long digits = SizeInBase(src, base);
96     string ans; ans.reserve(digits+1); // +1 to allow for minus sign
97     vector<char> buffer(digits+2); // +2 to allow for minus sign and terminating NUL
98     mpz_get_str(&buffer[0], base, mpzref(src));
99     ans = &buffer[0]; // Won't throw as space is already reserved.
100     return ans;
101   }
102 
103 
104   ostream& operator<<(ostream& out, const BigInt& N)
105   {
106     if (!out) return out;  // short-cut for bad ostreams
107 //    Using GMPXX next two lines should do it all...
108 //    mpz_class Ncopy(N.myRepr);
109 //    return out << Ncopy;
110 
111     // Dispose of the exceptional case n=0 immediately.
112     if (IsZero(N)) return out << '0';
113     const int base = (out.flags() & ios::oct) ? 8 :
114                      (out.flags() & ios::hex) ? 16 : 10;
115 
116     // prefix will contain sign and/or base specification
117     string prefix;
118 
119     // Firstly put the sign in the prefix...
120     if (N < 0) prefix += '-';
121     else if (out.flags() & ios::showpos) prefix += '+';
122 
123     // Next put base indication in the prefix if required...
124     if (out.flags() & ios::showbase)
125     {
126       if (base == 8 || base == 16) prefix += '0';
127       if (base == 16) prefix += 'x';
128     }
129 
130     out << prefix << ConvertToString(abs(N), base);
131     return out;
132   }
133 
134 
135   // Returns true if c is a valid digit for the given base
136   // (both upper and lower cases are allowed for hexadecimal).
137   // Note: base must be 8, 10 or 16 (otherwise always gives false)
IsDigitBase(char c,int base)138   bool IsDigitBase(char c, int base) // base = 8, 10 or 16
139   {
140     if (!(base == 10 || base == 8 || base == 16)) CoCoA_ERROR(ERR::BadArg, "IsDigitBase");
141     switch (base)
142     {
143     case 10:
144       return isdigit(c);
145     case 16:
146       return isxdigit(c);
147     case 8:
148       return (isdigit(c) &&  c != '8' && c != '9');
149     default:
150       return false; // should never get here
151     }
152   }
153 
154 
ScanUnsignedIntegerLiteral(std::istream & in)155   std::string ScanUnsignedIntegerLiteral(std::istream& in)
156   {
157     if (!in.good()) return string();
158     const int base = (in.flags() & ios::oct) ? 8 : (in.flags() & ios::hex) ? 16 : 10;
159 
160     // Read in as many digits as possible.
161     string digits;
162     while (true)
163     {
164       const char ch = in.peek(); // this may set eofbit
165       if (!in.good() || !IsDigitBase(ch, base)) break;
166       in.ignore();
167       digits += ch;
168     }
169     if (!in.good()) in.clear();
170     return digits;
171   }
172 
173 
174   std::istream& operator>>(std::istream& in, BigInt& N)
175   {
176     if (!in.good()) return in;
177     ws(in);
178 
179     // Look for sign of number.
180     const char FirstChar = in.peek(); // this may set eofbit
181     if (!in.good()) return in;
182     if (FirstChar == '-' || FirstChar == '+')
183       in.ignore();
184     ws(in); // allow whitespace between sign and the first digit
185 
186     const string digits = ScanUnsignedIntegerLiteral(in);
187     if (digits.empty())
188     {
189 // ***NOTE*** cannot "putback" if there was any whitespace after the sign
190 //      if (FirstChar == '-' || FirstChar == '+')
191 //        in.putback(FirstChar);
192       in.setstate(ios::failbit); // set failbit (perhaps in addition to eofbit)
193       return in;
194     }
195     if (in.eof()) in.clear();
196     // We found some digits, so convert them into a number.
197     N = BigIntFromString(digits); // could throw if number is huge.
198     if (FirstChar == '-') negate(N);
199     return in;
200   }
201 
202 
203   OpenMathOutput& operator<<(OpenMathOutput& OMOut, const BigInt& N)
204   {
205     OMOut->mySend(N);
206     return OMOut;
207   }
208 
209 
210   OpenMathInput& operator>>(OpenMathInput& OMIn, BigInt& /*N*/)
211   {
212     CoCoA_ERROR(ERR::NYI, "OpenMathInput fns");
213     return OMIn;
214   }
215 
216 
217   //---------------------------------------------------------------------------
218   // Assignment and assignment arithmetic functions
219 
220   BigInt& BigInt::operator+=(const BigInt& rhs)
221   {
222     mpz_add(myRepr, myRepr, rhs.myRepr);
223     return *this;
224   }
225 
226 
227   BigInt& BigInt::operator-=(const BigInt& rhs)
228   {
229     mpz_sub(myRepr, myRepr, rhs.myRepr);
230     return *this;
231   }
232 
233 
234   BigInt& BigInt::operator*=(const BigInt& rhs)
235   {
236     mpz_mul(myRepr, myRepr, rhs.myRepr);
237     return *this;
238   }
239 
240 
241   BigInt& BigInt::operator/=(const BigInt& rhs)
242   {
243     if (IsZero(rhs))
244       CoCoA_ERROR(ERR::DivByZero, "BigInt /= BigInt");
245 //???    if (rhs < 0 && !mpz_divisible_p(myRepr, mpzref(rhs)))
246 //???      CoCoA_ERROR(ERR::IntDivByNeg, "BigInt /= BigInt");
247     mpz_tdiv_q(myRepr, myRepr, rhs.myRepr);
248     return *this;
249   }
250 
251 
252   BigInt& BigInt::operator%=(const BigInt& rhs)
253   {
254     if (IsZero(rhs))
255       CoCoA_ERROR(ERR::ZeroModulus, "BigInt %= BigInt");
256 //???    if (rhs < 0 && !mpz_divisible_p(myRepr, mpzref(rhs)))
257 //???      CoCoA_ERROR(ERR::IntDivByNeg, "BigInt %= BigInt");
258     mpz_tdiv_r(myRepr, myRepr, rhs.myRepr);
259     return *this;
260   }
261 
262 
263   //---------------------------------------------------------------------------
264   // Assignment and assignment arithmetic with rhs a MachineInt
265 
266   BigInt& BigInt::operator= (const MachineInt& rhs)
267   {
268     if (IsNegative(rhs))
269       mpz_set_si(myRepr, AsSignedLong(rhs));
270     else
271       mpz_set_ui(myRepr, AsUnsignedLong(rhs));
272 
273     return *this;
274   }
275 
276 
277   BigInt& BigInt::operator+=(const MachineInt& rhs)
278   {
279     if (IsNegative(rhs))
280       mpz_sub_ui(myRepr, myRepr, negate(rhs));
281     else
282       mpz_add_ui(myRepr, myRepr, AsUnsignedLong(rhs));
283     return *this;
284   }
285 
286 
287   BigInt& BigInt::operator-=(const MachineInt& rhs)
288   {
289     if (IsNegative(rhs))
290       mpz_add_ui(myRepr, myRepr, negate(rhs));
291     else
292       mpz_sub_ui(myRepr, myRepr, AsUnsignedLong(rhs));
293     return *this;
294   }
295 
296 
297   BigInt& BigInt::operator*=(const MachineInt& rhs)
298   {
299     if (IsNegative(rhs))
300       mpz_mul_si(myRepr, myRepr, AsSignedLong(rhs));
301     else
302       mpz_mul_ui(myRepr, myRepr, AsUnsignedLong(rhs));
303     return *this;
304   }
305 
306 
307   BigInt& BigInt::operator/=(const MachineInt& rhs)
308   {
309     if (IsZero(rhs))
310       CoCoA_ERROR(ERR::DivByZero, "BigInt /= MachineInt");
311     if (IsNegative(rhs))
312       mpz_neg(myRepr, myRepr);
313 
314     mpz_tdiv_q_ui(myRepr, myRepr, uabs(rhs));
315     return *this;
316   }
317 
318 
319   BigInt& BigInt::operator%=(const MachineInt& rhs)
320   {
321     if (IsZero(rhs))
322       CoCoA_ERROR(ERR::ZeroModulus, "BigInt %= MachineInt");
323     mpz_tdiv_r_ui(myRepr, myRepr, uabs(rhs));
324     return *this;
325   }
326 
327 
328 
329   //---------------------------------------------------------------------------
330   // increment and decrement
331 
332   BigInt& BigInt::operator++()
333   {
334     mpz_add_ui(myRepr, myRepr, 1);
335     return *this;
336   }
337 
338 
339   BigInt& BigInt::operator--()
340   {
341     mpz_sub_ui(myRepr, myRepr, 1);
342     return *this;
343   }
344 
345 
346   const BigInt BigInt::operator++(int)  // INEFFICIENT
347   {
348     BigInt ans(*this);
349     ++*this;
350     return ans;
351   }
352 
353 
354   const BigInt BigInt::operator--(int)  // INEFFICIENT
355   {
356     BigInt ans(*this);
357     --*this;
358     return ans;
359   }
360 
361 
362   //---------------------------------------------------------------------------
363 
364 } // end of namespace CoCoA
365 
366 
367 
368 // The next few lines contain RCS header/log information.
369 // $Header: /Volumes/Home_1/cocoa/cvs-repository/CoCoALib-0.99/src/AlgebraicCore/BigInt.C,v 1.25 2019/03/19 11:07:07 abbott Exp $
370 // $Log: BigInt.C,v $
371 // Revision 1.25  2019/03/19 11:07:07  abbott
372 // Summary: Replaced 0 by nullptr where appropriate
373 //
374 // Revision 1.24  2018/06/13 12:33:19  abbott
375 // Summary: Corrected two error mesgs
376 //
377 // Revision 1.23  2018/05/18 12:13:36  bigatti
378 // -- renamed IntOperations --> BigIntOps
379 //
380 // Revision 1.22  2018/04/20 18:51:25  abbott
381 // Summary: Changed ctors for BigInt/BigRat from string or from MPZ/MPQ
382 //
383 // Revision 1.21  2016/11/11 14:15:32  abbott
384 // Summary: Added short-cut to operator<< when ostream is in bad state
385 //
386 // Revision 1.20  2016/10/08 19:45:04  abbott
387 // Summary: Exposed "new" fn ScanUnsignedIntegerLiteral (rtns a string)
388 //
389 // Revision 1.19  2016/08/02 12:49:34  abbott
390 // Summary: Renamed NumDigits to SizeInBase; updated doc.
391 //
392 // Revision 1.18  2016/07/21 15:13:06  abbott
393 // Summary: Removed some cruft
394 //
395 // Revision 1.17  2016/07/21 14:13:49  abbott
396 // Summary: Added new fn ScanUnsignedIntegerLiteral
397 //
398 // Revision 1.16  2015/10/09 18:26:36  abbott
399 // Summary: Corrected redmine reference
400 //
401 // Revision 1.15  2015/10/09 18:18:27  abbott
402 // Summary: Renamed "abs" to "uabs" for MachineInt; new fn "negate"; see redmine 783
403 //
404 // Revision 1.14  2013/03/26 14:56:06  abbott
405 // Updated the conversion fns (in ptic removed procedure "convert");
406 // numerous consequential changes.
407 //
408 // Revision 1.13  2013/02/14 15:35:48  abbott
409 // Added a cosmetic space.
410 //
411 // Revision 1.12  2012/05/28 09:18:21  abbott
412 // Created IntOperations which gathers together all operations on
413 // integers (both big and small).  Many consequential changes.
414 //
415 // Revision 1.11  2012/05/25 13:01:23  abbott
416 // Added fn IsDivisible.
417 //
418 // Revision 1.10  2012/02/07 10:47:12  bigatti
419 // -- updated comment to "BigInt"
420 //
421 // Revision 1.9  2011/11/09 14:03:40  bigatti
422 // -- renamed MachineInteger --> MachineInt
423 //
424 // Revision 1.8  2011/09/13 15:49:20  abbott
425 // Added "static" to log2 local var in log(BigInt).
426 //
427 // Revision 1.7  2011/09/06 15:21:53  abbott
428 // Changed "cmp" functions so that the return value is in {-1,0,+1}.
429 //
430 // Revision 1.6  2011/08/25 06:30:08  bigatti
431 // -- added log from ZZ.C
432 //
433 // Revision 1.5  2011/08/23 16:16:29  abbott
434 // Corrected defn of RoundDiv; corrected comment too.
435 //
436 // Revision 1.4  2011/08/17 11:56:57  abbott
437 // Added static_cast to keep compiler quiet.
438 //
439 // Revision 1.3  2011/08/14 15:52:17  abbott
440 // Changed ZZ into BigInt (phase 1: just the library sources).
441 //
442 // Revision 1.2  2011/08/12 16:31:03  abbott
443 // COMMENTED OUT SOME FNS SO THAT BigInt CAN EXIST ALONGSIDE ZZ
444 // FOR THE TIME BEING.
445 //
446 // Revision 1.1  2011/08/12 15:21:26  abbott
447 // Added BigInt impl (derived from ZZ); not used by anyone yet.
448 //
449 //------ log with old name ZZ.C -------------------------------
450 // Revision 1.28  2011/03/21 11:13:25  abbott
451 // Changed return type for operator%(ZZ,MachineInteger) from
452 // unsigned long to long to fit in with the new coding conventions.
453 //
454 // Revision 1.27  2011/03/14 10:32:22  abbott
455 // Changed size_t into long (return types of NumDigits & exponent).
456 //
457 // Revision 1.26  2011/03/01 15:27:23  abbott
458 // Improved impl of ILogBase -- faster in most cases.
459 // Changed the error objects thrown in certain cases (e.g. ERR::BadArg --> ERR::LogZero).
460 //
461 // Revision 1.25  2011/01/14 17:21:15  abbott
462 // Added isqrt, iroot, IsExactIroot, IsSquare, IsPower.
463 //
464 // Revision 1.24  2010/12/26 13:03:15  abbott
465 // Added ILogBase function (to BigInt & BigRat).
466 //
467 // Revision 1.23  2010/04/23 13:54:44  abbott
468 // binomial function now triggers error if 2nd arg is negative.
469 //
470 // Revision 1.22  2010/03/23 11:59:35  abbott
471 // Cleaned mantissa -- GMP already has a fn for this!
472 // Removed use of shared static "temporary" ZZ value -- caused GMPAllocator to report an error!
473 //
474 // Revision 1.21  2010/03/22 21:01:31  abbott
475 // Cleaned impl of binomial (& fixed a couple of silly bugs).
476 //
477 // Revision 1.20  2010/03/22 11:50:31  abbott
478 // Added ctor from a string.
479 // Fixed stupid bug in operator-.
480 //
481 // Revision 1.19  2010/03/18 16:41:08  abbott
482 // Commented out unused arg (in NYI fn).
483 //
484 // Revision 1.18  2010/03/18 13:54:19  abbott
485 // Added openmath output fns (moved from OpenMath files).
486 //
487 // Revision 1.17  2009/12/29 22:44:32  abbott
488 // Removed buggy proxy class ZZ::rtn.
489 // Consequent changes for function prototypes also in NumTheory.
490 // Corrected some minor buglets in NumTheory.
491 //
492 // Revision 1.16  2009/12/11 11:42:16  abbott
493 // Changed convert into IsConvertible.
494 // Cleaned impl of operator>>(istream&,ZZ&).
495 //
496 // Revision 1.15  2009/11/26 16:18:00  bigatti
497 // -- including string ZZ.C instead of ZZ.H
498 //
499 // Revision 1.14  2009/10/08 13:39:47  abbott
500 // Renamed "round" into "RoundDiv".
501 // Added some new versions of "RoundDiv".
502 // Added a test for "RoundDiv".
503 //
504 // Revision 1.13  2009/06/11 14:05:29  abbott
505 // CLEANING: Removed several functions which are now gathered in NumTheory.H/C
506 //           (for example: gcd, lcm, PowerMod, InvMod).
507 //
508 // Revision 1.12  2009/06/05 12:08:27  abbott
509 // Changed return type of operator%(ZZ,MachineInteger); it is now unsigned long
510 // instead of ZZ.
511 //
512 // Revision 1.11  2009/01/12 14:34:10  abbott
513 // Corrected IsDigitBase (following a bug report from anonymous)
514 // for octal and hexadecimal digits.  Added 3 lines of comment too.
515 //
516 // Revision 1.10  2008/12/16 21:14:47  abbott
517 // In functions taking a machine integer changed arg type from MachineInteger
518 // to const-ref-MachineInteger.
519 //
520 // Revision 1.9  2008/11/18 10:25:48  abbott
521 // Added function round.
522 //
523 // Revision 1.8  2008/04/22 13:09:16  abbott
524 // Removed IsPositive and IsNegative functions for ZZs.
525 // Comparison between RingElem and 0 is now handled specially (specially fast?).
526 //
527 // Revision 1.7  2007/10/30 17:14:07  abbott
528 // Changed licence from GPL-2 only to GPL-3 or later.
529 // New version for such an important change.
530 //
531 // Revision 1.6  2007/06/01 13:56:08  abbott
532 // Now gives error whenever you try to compute 0^0 -- previously some cases were not checked.
533 //
534 // Revision 1.5  2007/05/22 22:51:39  abbott
535 // Changed name of fn ndigits to NumDigits.
536 // Changed return type of exponent and NumDigits.
537 // Changed some exceptions from nonstandard to the appropriate standard one.
538 //
539 // Revision 1.4  2007/05/21 12:57:28  abbott
540 // New class for passing machine integers as args; includes some simple
541 // operations on machine integers (cmp, gcd, IsNegative,...).  Operations
542 // between ZZ and machine integers modified to use the new class.  Inexact
543 // integer division (of a ZZ) by a negative value now triggers an error;
544 // new error for reporting inexact integer division by a negative value.
545 //
546 // Revision 1.3  2007/03/23 18:38:42  abbott
547 // Separated the "convert" functions (and CheckedCast) into their own files.
548 // Many consequential changes.  Also corrected conversion to doubles.
549 //
550 // Revision 1.2  2007/03/16 17:43:05  abbott
551 // Added new convert function (from ZZ to double).
552 //
553 // Revision 1.1.1.1  2007/03/09 15:16:11  abbott
554 // Imported files
555 //
556 // Revision 1.9  2007/03/08 18:22:28  cocoa
557 // Just whitespace cleaning.
558 //
559 // Revision 1.8  2007/01/13 14:14:34  cocoa
560 // Overhaul of RingHom code: it nows uses SmartPtrIRC, and printing is more logical.
561 // Have not yet updated the documentation.
562 //
563 // Revision 1.7  2007/01/09 15:52:08  cocoa
564 // Changed QBGenerator to use std::vector instead of std::list for the result.
565 // Minor mod to configure script.
566 //
567 // Revision 1.6  2006/11/29 11:59:35  cocoa
568 // -- fixed: convert(double& z, const ZZ& num, const ZZ& den) now returns
569 //    bool (was void) and does not throw errors
570 //
571 // Revision 1.5  2006/11/27 13:06:22  cocoa
572 // Anna and Michael made me check without writing a proper message.
573 //
574 // Revision 1.4  2006/10/16 23:18:59  cocoa
575 // Corrected use of std::swap and various special swap functions.
576 // Improved myApply memfn for homs of RingDistrMPolyInlPP.
577 //
578 // Revision 1.3  2006/10/06 09:36:13  cocoa
579 // Fixed two minor bugs introduced at last check in.
580 //
581 // Revision 1.2  2006/09/29 11:46:54  cocoa
582 // Corrected bug in convert(ZZ, ZZ, double) -- now correct and simpler.
583 // Previously went into infinite loop on negative doubles.
584 //
585 // Revision 1.1.1.1  2006/05/30 11:39:37  cocoa
586 // Imported files
587 //
588 // Revision 1.5  2006/05/12 16:10:58  cocoa
589 // Added OpenMathFwd.H, and tidied OpenMath.H.
590 // Many consequential but trivial changes.
591 //
592 // Revision 1.4  2006/03/27 12:21:25  cocoa
593 // Minor silly changes to reduce number of complaints from some compiler or other.
594 //
595 // Revision 1.3  2006/03/14 15:01:49  cocoa
596 // Improved the implementation of ring member fns for computing powers.
597 // Should keep Intel C++ compiler quieter too.
598 //
599 // Revision 1.2  2006/03/12 21:28:33  cocoa
600 // Major check in after many changes
601 //
602 // Revision 1.1.1.1  2005/10/17 10:46:54  cocoa
603 // Imported files
604 //
605 // Revision 1.2  2005/08/08 16:36:32  cocoa
606 // Just checking in before going on holiday.
607 // Don't really recall what changes have been made.
608 // Added IsIndet function for RingElem, PPMonoidElem,
609 // and a member function of OrdvArith.
610 // Improved the way failed assertions are handled.
611 //
612 // Revision 1.1.1.1  2005/05/03 15:47:31  cocoa
613 // Imported files
614 //
615 // Revision 1.3  2005/04/20 15:40:47  cocoa
616 // Major change: modified the standard way errors are to be signalled
617 // (now via a macro which records filename and line number).  Updated
618 // documentation in error.txt accordingly.
619 //
620 // Improved the documentation in matrix.txt (still more work to be done).
621 //
622 // Revision 1.2  2005/04/19 14:06:03  cocoa
623 // Added GPL and GFDL licence stuff.
624 //
625 // Revision 1.1.1.1  2005/01/27 15:12:13  cocoa
626 // Imported files
627 //
628 // Revision 1.8  2004/11/12 15:49:29  cocoa
629 // Tidying prior to 0.90 release.
630 // (a) documentation improved (or marked as poor)
631 // (b) sundry minor improvements to the code
632 //
633 // Revision 1.7  2004/11/05 15:36:57  cocoa
634 // Removed call to new(nothrow) inside a convert function.  Replaced
635 // it by use of a std::vector -- code is certainly cleaner and clearer
636 // now, but possibly with an inconsequential reduction in run-time
637 // performance.
638 //
639 // Revision 1.6  2004/11/04 18:47:42  cocoa
640 // (1) Ring member functions which previously expected mpz_t args
641 //     now expect ZZ args.  Numerous minor consequential changes.
642 // (2) Renamed function which gives access to the mpz_t value inside
643 //     a ZZ object: previously was raw(...), now is mpzref(...).
644 //     Plenty of calls had to be altered.
645 //
646 // Revision 1.5  2004/05/27 16:14:02  cocoa
647 // Minor revision for new coding conventions.
648 //
649 // Revision 1.4  2004/05/24 15:52:13  cocoa
650 // Major update:
651 //   new error mechanism
652 //   many fixes
653 //   RingHoms almost work now
654 //   RingFloat much improved
655 //
656 // Revision 1.3  2004/02/03 16:16:20  cocoa
657 // Removed pointless IamGCDDomain functions from several concrete rings.
658 // Added IamOrderedDomain functions where appropriate.
659 // Tidied ctors for the small finite fields.
660 //
661 // Revision 1.2  2003/10/17 10:51:06  cocoa
662 // Major cleaning, and new naming convention.
663 //
664 // Revision 1.1.1.1  2003/09/24 12:55:43  cocoa
665 // Imported files
666 //
667 // Revision 1.2  2003/06/23 16:13:01  abbott
668 // Minor cleaning prior to public release.
669 //
670 // Revision 1.1  2003/05/14 17:12:40  abbott
671 // Initial revision
672 //
673