Negative() 공개 메소드

public Negative ( ) : void
리턴 void
예제 #1
0
        //***********************************************************************
        // Modulo Exponentiation
        //***********************************************************************

        public BigInteger ModPow(BigInteger exp, BigInteger n)
        {
            if ((exp.Data[maxLength - 1] & 0x80000000) != 0)
            {
                throw (new ArithmeticException("Positive exponents only."));
            }

            BigInteger resultNum = 1;
            BigInteger tempNum;
            bool       thisNegative = false;

            if ((this.Data[maxLength - 1] & 0x80000000) != 0)   // negative this
            {
                tempNum      = -this % n;
                thisNegative = true;
            }
            else
            {
                tempNum = this % n;                        // ensures (tempNum * tempNum) < b^(2k)
            }
            if ((n.Data[maxLength - 1] & 0x80000000) != 0) // negative n
            {
                n = -n;
            }

            // calculate constant = b^(2k) / m
            var constant = new BigInteger(0);

            int i = n.Length << 1;

            constant.Data[i] = 0x00000001;
            constant.Length  = i + 1;
            constant.Divide(n);
            //constant /= n;
            int totalBits = exp.bitCount();
            int count     = 0;
            var temp      = new BigInteger(0);

            // perform squaring and multiply exponentiation
            for (var pos = 0; pos < exp.Length; pos++)
            {
                uint mask = 0x01;
                //Console.WriteLine("pos = " + pos);

                for (var index = 0; index < 32; index++)
                {
                    if ((exp.Data[pos] & mask) != 0)
                    {
                        BarrettReduction(ref resultNum, tempNum, n, constant, ref temp);
                    }
                    mask <<= 1;
                    BarrettReduction(ref tempNum, tempNum, n, constant, ref temp);

                    if (tempNum.Length == 1 && tempNum.Data[0] == 1)
                    {
                        if (thisNegative && (exp.Data[0] & 0x1) != 0)    //odd exp
                        {
                            resultNum.Negative();
                        }
                        return(resultNum);
                    }
                    count++;
                    if (count == totalBits)
                    {
                        break;
                    }
                }
            }
            constant.Recycle();
            temp.Recycle();
            if (thisNegative && (exp.Data[0] & 0x1) != 0)    //odd exp
            {
                resultNum.Negative();
            }

            return(resultNum);
        }
예제 #2
0
        public static void Multiply(BigInteger bi1, BigInteger bi2, ref BigInteger result)
        {
            const int lastPos = maxLength - 1;
            bool      bi1Neg = false, bi2Neg = false;

            // take the absolute value of the inputs
            try
            {
                if ((bi1.Data[lastPos] & 0x80000000) != 0)     // bi1 negative
                {
                    bi1Neg = true; bi1 = -bi1;
                }
                if ((bi2.Data[lastPos] & 0x80000000) != 0)     // bi2 negative
                {
                    bi2Neg = true; bi2 = -bi2;
                }
            }
            catch (Exception) { }

            result.Clear();

            // multiply the absolute values
            try
            {
                for (int i = 0; i < bi1.Length; i++)
                {
                    if (bi1.Data[i] == 0)
                    {
                        continue;
                    }

                    ulong mcarry = 0;
                    for (int j = 0, k = i; j < bi2.Length; j++, k++)
                    {
                        // k = i + j
                        ulong val = ((ulong)bi1.Data[i] * (ulong)bi2.Data[j]) +
                                    (ulong)result.Data[k] + mcarry;

                        result.Data[k] = (uint)val;
                        mcarry         = (val >> 32);
                    }

                    if (mcarry != 0)
                    {
                        result.Data[i + bi2.Length] = (uint)mcarry;
                    }
                }
            }
            catch (Exception)
            {
                throw (new ArithmeticException("Multiplication overflow."));
            }


            result.Length = bi1.Length + bi2.Length;
            if (result.Length > maxLength)
            {
                result.Length = maxLength;
            }

            while (result.Length > 1 && result.Data[result.Length - 1] == 0)
            {
                result.Length--;
            }

            // overflow check (result is -ve)
            if ((result.Data[lastPos] & 0x80000000) != 0)
            {
                if (bi1Neg != bi2Neg && result.Data[lastPos] == 0x80000000)    // different sign
                {
                    // handle the special case where multiplication produces
                    // a max negative number in 2's complement.

                    if (result.Length == 1)
                    {
                        return;
                    }
                    else
                    {
                        bool isMaxNeg = true;
                        for (int i = 0; i < result.Length - 1 && isMaxNeg; i++)
                        {
                            if (result.Data[i] != 0)
                            {
                                isMaxNeg = false;
                            }
                        }

                        if (isMaxNeg)
                        {
                            return;
                        }
                    }
                }

                throw (new ArithmeticException("Multiplication overflow."));
            }

            // if input has different signs, then result is -ve
            if (bi1Neg != bi2Neg)
            {
                result.Negative();
            }
            return;
        }
예제 #3
0
        public static void Multiply(BigInteger bi1, BigInteger bi2,ref BigInteger result)
        {
            const int lastPos = maxLength - 1;
            bool bi1Neg = false, bi2Neg = false;

            // take the absolute value of the inputs
            try
            {
                if ((bi1.Data[lastPos] & 0x80000000) != 0)     // bi1 negative
                {
                    bi1Neg = true; bi1 = -bi1;
                }
                if ((bi2.Data[lastPos] & 0x80000000) != 0)     // bi2 negative
                {
                    bi2Neg = true; bi2 = -bi2;
                }
            }
            catch (Exception) { }

            result.Clear();

            // multiply the absolute values
            try
            {
                for (int i = 0; i < bi1.Length; i++)
                {
                    if (bi1.Data[i] == 0) continue;

                    ulong mcarry = 0;
                    for (int j = 0, k = i; j < bi2.Length; j++, k++)
                    {
                        // k = i + j
                        ulong val = ((ulong)bi1.Data[i] * (ulong)bi2.Data[j]) +
                                    (ulong)result.Data[k] + mcarry;

                        result.Data[k] = (uint)val;
                        mcarry = (val >> 32);
                    }

                    if (mcarry != 0)
                        result.Data[i + bi2.Length] = (uint)mcarry;
                }
            }
            catch (Exception)
            {
                throw (new ArithmeticException("Multiplication overflow."));
            }


            result.Length = bi1.Length + bi2.Length;
            if (result.Length > maxLength)
                result.Length = maxLength;

            while (result.Length > 1 && result.Data[result.Length - 1] == 0)
                result.Length--;

            // overflow check (result is -ve)
            if ((result.Data[lastPos] & 0x80000000) != 0)
            {
                if (bi1Neg != bi2Neg && result.Data[lastPos] == 0x80000000)    // different sign
                {
                    // handle the special case where multiplication produces
                    // a max negative number in 2's complement.

                    if (result.Length == 1)
                        return;
                    else
                    {
                        bool isMaxNeg = true;
                        for (int i = 0; i < result.Length - 1 && isMaxNeg; i++)
                        {
                            if (result.Data[i] != 0)
                                isMaxNeg = false;
                        }

                        if (isMaxNeg)
                            return;
                    }
                }

                throw (new ArithmeticException("Multiplication overflow."));
            }

            // if input has different signs, then result is -ve
            if (bi1Neg != bi2Neg) result.Negative();
            return;
        }