-/*
- * The steps for construction of a BigUnsigned
- * from an integral value x are as follows:
- * 1. If x is zero, create an empty BigUnsigned and stop.
- * 2. If x is negative, throw an exception.
- * 3. Allocate a one-block number array.
- * 4. If x is of a signed type, convert x to the unsigned
- * type of the same length.
- * 5. Expand x to a Blk, and store it in the number array.
- *
- * Since 2005.01.06, NumberlikeArray uses `NULL' rather
- * than a real array if one of zero length is needed.
- * These constructors implicitly call NumberlikeArray's
- * default constructor, which sets `blk = NULL, cap = len = 0'.
- * So if the input number is zero, they can just return.
- * See remarks in `NumberlikeArray.hh'.
- */
-
-BigUnsigned::BigUnsigned(unsigned long x) {
- if (x == 0)
- ; // NumberlikeArray already did all the work
- else {
- cap = 1;
- blk = new Blk[1];
- len = 1;
- blk[0] = Blk(x);
- }
-}
-
-BigUnsigned::BigUnsigned(long x) {
- if (x == 0)
- ;
- else if (x > 0) {
- cap = 1;
- blk = new Blk[1];
- len = 1;
- blk[0] = Blk(x);
- } else
- throw "BigUnsigned::BigUnsigned(long): Cannot construct a BigUnsigned from a negative number";
-}
-
-BigUnsigned::BigUnsigned(unsigned int x) {
- if (x == 0)
- ;
- else {
- cap = 1;
- blk = new Blk[1];
- len = 1;
- blk[0] = Blk(x);
- }
-}
-
-BigUnsigned::BigUnsigned(int x) {
- if (x == 0)
- ;
- else if (x > 0) {
- cap = 1;
- blk = new Blk[1];
- len = 1;
- blk[0] = Blk(x);
- } else
- throw "BigUnsigned::BigUnsigned(int): Cannot construct a BigUnsigned from a negative number";
-}
-
-BigUnsigned::BigUnsigned(unsigned short x) {
- if (x == 0)
- ;
- else {
- cap = 1;
- blk = new Blk[1];
- len = 1;
- blk[0] = Blk(x);
- }
-}
-
-BigUnsigned::BigUnsigned(short x) {
- if (x == 0)
- ;
- else if (x > 0) {
- cap = 1;
- blk = new Blk[1];
- len = 1;
- blk[0] = Blk(x);
- } else
- throw "BigUnsigned::BigUnsigned(short): Cannot construct a BigUnsigned from a negative number";
-}
-
-// CONVERTERS
-/*
- * The steps for conversion of a BigUnsigned to an
- * integral type are as follows:
- * 1. If the BigUnsigned is zero, return zero.
- * 2. If it is more than one block long or its lowest
- * block has bits set out of the range of the target
- * type, throw an exception.
- * 3. Otherwise, convert the lowest block to the
- * target type and return it.
- */
-
-namespace {
- // These masks are used to test whether a Blk has bits
- // set out of the range of a smaller integral type. Note
- // that this range is not considered to include the sign bit.
- const BigUnsigned::Blk lMask = ~0 >> 1;
- const BigUnsigned::Blk uiMask = (unsigned int)(~0);
- const BigUnsigned::Blk iMask = uiMask >> 1;
- const BigUnsigned::Blk usMask = (unsigned short)(~0);
- const BigUnsigned::Blk sMask = usMask >> 1;
-}
-
-BigUnsigned::operator unsigned long() const {
- if (len == 0)
- return 0;
- else if (len == 1)
- return (unsigned long) blk[0];
- else
- throw "BigUnsigned::operator unsigned long: Value is too big for an unsigned long";
-}
-
-BigUnsigned::operator long() const {
- if (len == 0)
- return 0;
- else if (len == 1 && (blk[0] & lMask) == blk[0])
- return (long) blk[0];
- else
- throw "BigUnsigned::operator long: Value is too big for a long";
-}
-
-BigUnsigned::operator unsigned int() const {
- if (len == 0)
- return 0;
- else if (len == 1 && (blk[0] & uiMask) == blk[0])
- return (unsigned int) blk[0];
- else
- throw "BigUnsigned::operator unsigned int: Value is too big for an unsigned int";
-}
-
-BigUnsigned::operator int() const {
- if (len == 0)
- return 0;
- else if (len == 1 && (blk[0] & iMask) == blk[0])
- return (int) blk[0];
- else
- throw "BigUnsigned::operator int: Value is too big for an int";
-}