Esempio n. 1
0
        public static MyBigType operator >>(MyBigType leftSide, int shiftCount)
        {
            if (leftSide == null)
            {
                throw new ArgumentNullException("leftSide");
            }

            ArrayForDigits da = new ArrayForDigits(leftSide.m_digits);

            da.DataUsed = da.ShiftRight(shiftCount);

            if (leftSide.IsNegative)
            {
                for (int i = da.Count - 1; i >= da.DataUsed; i--)
                {
                    da[i] = ArrayForDigits.AllBits;
                }

                unsignIn mask = ArrayForDigits.HiBitSet;
                for (int i = 0; i < ArrayForDigits.DataSizeBits; i++)
                {
                    if ((da[da.DataUsed - 1] & mask) == ArrayForDigits.HiBitSet)
                    {
                        break;
                    }
                    da[da.DataUsed - 1] |= mask;
                    mask >>= 1;
                }
                da.DataUsed = da.Count;
            }

            return(new MyBigType(da));
        }
Esempio n. 2
0
 static ArrayForDigits()
 {
     unchecked
     {
         AllBits  = (unsignIn) ~((unsignIn)0);
         HiBitSet = (unsignIn)(((unsignIn)1) << (DataSizeBits) - 1);
     }
 }
Esempio n. 3
0
        private static void SingleDivide(MyBigType leftSide, MyBigType rightSide, out MyBigType quotient, out MyBigType remainder)
        {
            if (rightSide.IsZero)
            {
                throw new DivideByZeroException();
            }

            ArrayForDigits remainderDigits = new ArrayForDigits(leftSide.m_digits);

            remainderDigits.ResetDataUsed();

            int   pos      = remainderDigits.DataUsed - 1;
            ulong divisor  = (ulong)rightSide.m_digits[0];
            ulong dividend = (ulong)remainderDigits[pos];

            unsignIn[] result = new unsignIn[leftSide.m_digits.Count];
            leftSide.m_digits.CopyTo(result, 0, result.Length);
            int resultPos = 0;

            if (dividend >= divisor)
            {
                result[resultPos++]  = (unsignIn)(dividend / divisor);
                remainderDigits[pos] = (unsignIn)(dividend % divisor);
            }
            pos--;

            while (pos >= 0)
            {
                dividend                 = ((ulong)(remainderDigits[pos + 1]) << ArrayForDigits.DataSizeBits) + (ulong)remainderDigits[pos];
                result[resultPos++]      = (unsignIn)(dividend / divisor);
                remainderDigits[pos + 1] = 0;
                remainderDigits[pos--]   = (unsignIn)(dividend % divisor);
            }
            remainder = new MyBigType(remainderDigits);

            ArrayForDigits quotientDigits = new ArrayForDigits(resultPos + 1, resultPos);
            int            j = 0;

            for (int i = quotientDigits.DataUsed - 1; i >= 0; i--, j++)
            {
                quotientDigits[j] = result[i];
            }
            quotient = new MyBigType(quotientDigits);
        }
Esempio n. 4
0
        internal int ShiftLeftWithoutOverflow(int shiftCount)
        {
            if (shiftCount == 0)
            {
                return(m_data.Length);
            }

            List <unsignIn> temporary   = new List <unsignIn>(m_data);
            int             shiftAmount = ArrayForDigits.DataSizeBits;

            for (int count = shiftCount; count > 0; count -= shiftAmount)
            {
                if (count < shiftAmount)
                {
                    shiftAmount = count;
                }

                ulong carry = 0;
                for (int i = 0; i < temporary.Count; i++)
                {
                    ulong val = ((ulong)temporary[i]) << shiftAmount;
                    val |= carry;

                    temporary[i] = (unsignIn)(val & ArrayForDigits.AllBits);
                    carry        = (val >> ArrayForDigits.DataSizeBits);
                }

                if (carry != 0)
                {
                    unsignIn lastNum = (unsignIn)carry;
                    if (IsNegative)
                    {
                        int byteCount = (int)Math.Floor(Math.Log(carry, 2));
                        lastNum = (0xffffffff << byteCount) | (unsignIn)carry;
                    }

                    temporary.Add(lastNum);
                }
            }
            m_data = new unsignIn[temporary.Count];
            temporary.CopyTo(m_data);
            return(m_data.Length);
        }
Esempio n. 5
0
        private void ConstructFrom(byte[] array, int offset, int length)
        {
            if (array == null)
            {
                throw new ArgumentNullException("array");
            }
            if (offset > array.Length || length > array.Length)
            {
                throw new ArgumentOutOfRangeException("offset");
            }
            if (length > array.Length || (offset + length) > array.Length)
            {
                throw new ArgumentOutOfRangeException("length");
            }

            int isSize   = length / 4;
            int leftOver = length & 3;

            if (leftOver != 0)
            {
                ++isSize;
            }

            m_digits = new ArrayForDigits(isSize + 1, 0); // alloc one extra since we can't init -'s from here.

            for (int i = offset + length - 1, j = 0; (i - offset) >= 3; i -= 4, j++)
            {
                m_digits[j] = (unsignIn)((array[i - 3] << 24) + (array[i - 2] << 16) + (array[i - 1] << 8) + array[i]);
                m_digits.DataUsed++;
            }

            unsignIn accumulator = 0;

            for (int i = leftOver; i > 0; i--)
            {
                unsignIn digit = array[offset + leftOver - i];
                digit        = (digit << ((i - 1) * 8));
                accumulator |= digit;
            }
            m_digits[m_digits.DataUsed] = accumulator;

            m_digits.ResetDataUsed();
        }
Esempio n. 6
0
        private static void MultiDivide(MyBigType leftSide, MyBigType rightSide, out MyBigType quotient, out MyBigType remainder)
        {
            if (rightSide.IsZero)
            {
                throw new DivideByZeroException();
            }

            unsignIn val = rightSide.m_digits[rightSide.m_digits.DataUsed - 1];
            int      d   = 0;

            for (uint mask = ArrayForDigits.HiBitSet; mask != 0 && (val & mask) == 0; mask >>= 1)
            {
                d++;
            }

            int remainderLen = leftSide.m_digits.DataUsed + 1;

            unsignIn[] remainderDat = new unsignIn[remainderLen];
            leftSide.m_digits.CopyTo(remainderDat, 0, leftSide.m_digits.DataUsed);

            ArrayForDigits.ShiftLeft(remainderDat, d);
            rightSide = rightSide << d;

            ulong firstDivisor  = rightSide.m_digits[rightSide.m_digits.DataUsed - 1];
            ulong secondDivisor = (rightSide.m_digits.DataUsed < 2 ? (unsignIn)0 : rightSide.m_digits[rightSide.m_digits.DataUsed - 2]);

            int            divisorLen   = rightSide.m_digits.DataUsed + 1;
            ArrayForDigits dividendPart = new ArrayForDigits(divisorLen, divisorLen);

            unsignIn[] result    = new unsignIn[leftSide.m_digits.Count + 1];
            int        resultPos = 0;

            ulong carryBit = (ulong)0x1 << ArrayForDigits.DataSizeBits; // 0x100000000

            for (int j = remainderLen - rightSide.m_digits.DataUsed, pos = remainderLen - 1; j > 0; j--, pos--)
            {
                ulong dividend = ((ulong)remainderDat[pos] << ArrayForDigits.DataSizeBits) + (ulong)remainderDat[pos - 1];
                ulong qHat     = (dividend / firstDivisor);
                ulong rHat     = (dividend % firstDivisor);

                while (pos >= 2)
                {
                    if (qHat == carryBit || (qHat * secondDivisor) > ((rHat << ArrayForDigits.DataSizeBits) + remainderDat[pos - 2]))
                    {
                        qHat--;
                        rHat += firstDivisor;
                        if (rHat < carryBit)
                        {
                            continue;
                        }
                    }
                    break;
                }

                for (int h = 0; h < divisorLen; h++)
                {
                    dividendPart[divisorLen - h - 1] = remainderDat[pos - h];
                }

                MyBigType dTemp = new MyBigType(dividendPart);
                MyBigType rTemp = rightSide * (long)qHat;
                while (rTemp > dTemp)
                {
                    qHat--;
                    rTemp -= rightSide;
                }

                rTemp = dTemp - rTemp;
                for (int h = 0; h < divisorLen; h++)
                {
                    remainderDat[pos - h] = rTemp.m_digits[rightSide.m_digits.DataUsed - h];
                }

                result[resultPos++] = (unsignIn)qHat;
            }

            Array.Reverse(result, 0, resultPos);
            quotient = new MyBigType(new ArrayForDigits(result));

            int            n   = ArrayForDigits.ShiftRight(remainderDat, d);
            ArrayForDigits rDA = new ArrayForDigits(n, n);

            rDA.CopyFrom(remainderDat, 0, 0, rDA.DataUsed);
            remainder = new MyBigType(rDA);
        }