/* Module: BIGINT.CPP Author: William A. Rossi 175 Burnt Hill Rd Hope, RI 02831 bill@rossi.com Version: 1.0 Release Date: 31-AUG-1995 Description: BIGINT is an unsigned N-bit integer math class for the C++ programming language. ********************************************************************* The code contained in this file is in the public domain. Specifically, I give to the public domain all rights for future licensing of the source code, all resale rights, and all publishing rights. If you find this code useful, or have any comments I can be reached by email and snail mail at the above addresses. Disclaimer of Warranty THIS PACKAGE IS RELEASED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSES OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. YOU ASSUME THE ENTIRE RISK OF USING THE PROGRAM AND THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL THE AUTHOR BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF THE AUTHOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. */ #include #include "bigint.h" /********** Global constants ***************/ bigint bigint::zero; bigint bigint::one; bigint bigint::two; /* operator>>() operator<<() operator>>=() operator<<=() These are the shift operators. They are fundamenal operators */ bigint bigint::operator>>(int shift) { BIGINT_TEMPORARY bigint a, t; BIGINT_BASE msb = BIGINT_BASE_MAX ^ (BIGINT_BASE_MAX >> 1); int i, j; t = *this; for (i=0; i> 1; for (j=BIGINTSIZE-2; j>=0; j--) { a.data[j] = t.data[j] >> 1; if ((t.data[j+1] & 1) != 0) a.data[j] |= msb; /* Set most sig. bit */ } t = a; } return a; } bigint bigint::operator<<(int shift) { BIGINT_TEMPORARY bigint a, t; BIGINT_BASE msb = BIGINT_BASE_MAX ^ (BIGINT_BASE_MAX >> 1); int i, j; t = *this; for (i=0; i>=(int shift) { BIGINT_BASE msb = BIGINT_BASE_MAX ^ (BIGINT_BASE_MAX >> 1); BIGINT_BASE carry; int i, j; for (i=0; i>= 1; for (j=BIGINTSIZE-2; j>=0; j--) { if (carry) { carry = data[j] & 1; data[j] >>= 1; data[j] |= msb; } else { carry = data[j] & 1; data[j] >>= 1; } } } return *this; } bigint& bigint::operator<<=(int shift) { BIGINT_BASE msb = BIGINT_BASE_MAX ^ (BIGINT_BASE_MAX >> 1); BIGINT_BASE carry; int i, j; for (i=0; i() operator<=() operator>=() These operators compare two numbers starting at the most significant digit, and working back to the least significant. The differ only in the return codes they produce. */ int bigint::operator<(const bigint& q) { int i; for (i=(BIGINTSIZE-1); i>=0; i--) { if (data[i] < q.data[i]) return 1; if (data[i] > q.data[i]) return 0; } return 0; } int bigint::operator>(const bigint& q) { int i; for (i=(BIGINTSIZE-1); i>=0; i--) { if (data[i] < q.data[i]) return 0; if (data[i] > q.data[i]) return 1; } return 0; } int bigint::operator<=(const bigint& q) { int i; for (i=(BIGINTSIZE-1); i>=0; i--) { if (data[i] < q.data[i]) return 1; if (data[i] > q.data[i]) return 0; } return 1; } int bigint::operator>=(const bigint& q) { int i; for (i=(BIGINTSIZE-1); i>=0; i--) { if (data[i] < q.data[i]) return 0; if (data[i] > q.data[i]) return 1; } return 1; } /* operator&() operator|() operator^() operator&=() operator|=() operator^=() operator~() These operators perform the corresponding bitwise operations, on a per digit basis. */ bigint bigint::operator&(const bigint& q) { BIGINT_TEMPORARY bigint result; int i; for (i=(BIGINTSIZE-1); i>=0; i--) result.data[i] = data[i] & q.data[i]; return result; } bigint bigint::operator|(const bigint& q) { BIGINT_TEMPORARY bigint result; int i; for (i=(BIGINTSIZE-1); i>=0; i--) result.data[i] = data[i] | q.data[i]; return result; } bigint bigint::operator^(const bigint& q) { BIGINT_TEMPORARY bigint result; int i; for (i=(BIGINTSIZE-1); i>=0; i--) result.data[i] = data[i] ^ q.data[i]; return result; } bigint& bigint::operator&=(const bigint& q) { int i; for (i=(BIGINTSIZE-1); i>=0; i--) data[i] = data[i] & q.data[i]; return *this; } bigint& bigint::operator|=(const bigint& q) { int i; for (i=(BIGINTSIZE-1); i>=0; i--) data[i] = data[i] | q.data[i]; return *this; } bigint& bigint::operator^=(const bigint& q) { int i; for (i=(BIGINTSIZE-1); i>=0; i--) data[i] = data[i] ^ q.data[i]; return *this; } bigint bigint::operator~() { BIGINT_TEMPORARY bigint result; int i; for (i=(BIGINTSIZE-1); i>=0; i--) result.data[i] = ~data[i]; return result; } /* operator*() This operator performs multiplication by shift and add. */ bigint bigint::operator*(bigint q) { BIGINT_TEMPORARY bigint t; BIGINT_TEMPORARY bigint p; p = zero; t = *this; do { if ((q.data[0] & 1) != 0) p += t; q >>= 1; t <<= 1; } while (q != zero); return p; } #if 0 // There is a bug in operator*=() at the moment... // It does not produce the same results as operator*(). bigint& bigint::operator*=(bigint q) { BIGINT_TEMPORARY bigint t; BIGINT_TEMPORARY bigint& p=*this; t = *this; p = zero; do { if ((q.data[0] & 1) != 0) p += t; q >>= 1; t <<= 1; } while (q != zero); return *this; } #endif bigint bigint::Divide(bigint a, bigint b, bigint *remainder) { BIGINT_TEMPORARY bigint c, d; BIGINT_TEMPORARY BIGINT_BASE msb = BIGINT_BASE_MAX ^ (BIGINT_BASE_MAX >> 1); int i, shiftcnt=0; /* Check for attempt to divide by zero */ if (b == zero) shiftcnt = 1 / shiftcnt; // Force a divide by zero exception. (shiftcnt=0) c=zero; d=b; /* Store the divisor in D */ /* Left shift B until it is greater than or equal to A */ while (ba) /* If B is greater than A, right shift B */ { b >>= 1; shiftcnt--; } for(i=0; i<=shiftcnt; i++) { if (b<=a) /* If B is greater than A, then the bit is a 1 */ { a -= b; /* Subtract B from A */ b >>= 1; /* Right shift B */ c <<= 1; /* Left shift quotient */ c++; /* Increment quotient */ } else { b >>= 1; /* Bit is 0, right shift B, left shift quotient */ c <<= 1; } } if (remainder != NULL) *remainder = a; return c; } bigint bigint::sqrt() /* returns the square root of this */ { BIGINT_TEMPORARY bigint x,y,dx; bigint mask = two; int i,j; mask = -mask; y = *this; for (i=0,x=y;x!=zero;x>>=1,i++); for (j=0,x=y;j<(unsigned long)(i>>1);x>>=1,j++); do { /* We are really performing the fuction: dx = (y/x - x) / 2; below, but since these are unsigned numbers, we MUST do the subtraction last in order for the x = x + dx; equation to work properly. */ dx = (y>>1)/x - (x>>1); x = x + dx; } while ((dx &= mask) != zero); return x; } /********************* Class definitions end here *******************/