Exemple #1
0
        public static BigFloat Multiply(BigFloat a, BigFloat b)
        {
            a = (BigFloat)a.Clone();
            b = (BigFloat)b.Clone();

            if (b.Length > a.Length)              // then switch them around
            {
                BigFloat temp = a;
                a = b;
                b = temp;
            }

            BigFloat        retval = new BigFloat();
            List <BigFloat> rows   = new List <BigFloat>();

            retval._sign = a.Sign == b.Sign;
            retval._exp  = a._exp + b._exp;

            // for each digit in b
            for (int i = 0; i < b.Length; i++)
            {
                BigFloat row = new BigFloat();
                row._exp = retval._exp;

                Int32 digit = 0, carry = 0;
                for (int exp = 0; exp < i; exp++)
                {
                    row._data.Add(0);                         // pad with zeros to the right
                }
                for (int j = 0; j < a.Length; j++)            // perform per-digit multiplication of a against b
                {
                    digit = a[j] * b[i] + carry;
                    carry = digit / 10;
                    digit = digit % 10;
                    row._data.Add((SByte)digit);
                }

                // reduce the carry
                while (carry > 0)
                {
                    digit = carry % 10;
                    carry = carry / 10;
                    row._data.Add((SByte)digit);
                }

                rows.Add(row);
            }

            // sum the rows to give the result
            foreach (BigFloat row in rows)
            {
                retval = (BigFloat)retval.Add(row);
            }

            retval.Normalise();

            return(retval);
        }
Exemple #2
0
        public static BigFloat Divide(BigFloat dividend, BigFloat divisor, out Boolean isExact)
        {
            if (divisor.IsZero)
            {
                throw new DivideByZeroException();
            }

            isExact = true;
            if (dividend.IsZero)
            {
                return((BigFloat)dividend.Clone());
            }

            ///////////////////////////////

            BigFloat quotient = new BigFloat();

            quotient._sign = dividend.Sign == divisor.Sign;

            dividend = (BigFloat)dividend.Absolute();
            divisor  = (BigFloat)divisor.Absolute();

            BigFloat aPortion;
            BigFloat bDigit = null;

            //////////////////////////////

            while (divisor[0] == 0)                // remove least-significant zeros and up the exponent to compensate
            {
                divisor._exp++;
                divisor._data.RemoveAt(0);
            }
            quotient._exp = dividend.Length + dividend._exp - divisor.Length - divisor._exp + 1;
            dividend._exp = 0;
            divisor._exp  = 0;

            aPortion = new BigFloat();

            Int32   bump = 0, c = -1;
            Boolean hump = false;

            isExact = false;

            while (quotient.Length < _divisionDigits)                // abandon hope all ye who enter here

            {
                aPortion = dividend.Msd(divisor.Length + (hump ? 1 : 0));

                if (aPortion < divisor)
                {
                    int i = 1;
                    while (aPortion < divisor)
                    {
                        aPortion = dividend.Msd(divisor.Length + i + (hump ? 1 : 0));
                        quotient._exp--;
                        quotient._data.Add(0);
                        i++;
                    }
                    hump = true;
                }

                bDigit = 0;                 //tt = 0;
                c      = 0;
                while (bDigit < aPortion)
                {
                    bDigit = (BigFloat)bDigit.Add(divisor);                     //tt += b;
                    c++;
                }
                if (bDigit != aPortion)
                {
                    c--;
                    bDigit  = new BigFloat(c);
                    bDigit  = (BigFloat)bDigit.Multiply(divisor);                    //tt *= b;
                    isExact = false;
                }
                else
                {
                    isExact = true;
                }

                quotient._data.Add((sbyte)c);
                quotient._exp--;

                aPortion.Normalise();
                dividend.Normalise();

                bump = aPortion.Length - bDigit.Length;
                if (aPortion.Length > dividend.Length)
                {
                    dividend = aPortion;
                }
                bDigit = bDigit.Msd(dividend.Length - bump);

                aPortion = BigFloat.Add(dividend, (BigFloat)bDigit.Negate(), false);

                dividend = (BigFloat)aPortion.Clone();

                if (aPortion.IsZero)
                {
                    break;                                   // no more work necessary
                }
                if (hump)
                {
                    if (dividend[dividend.Length - 1] == 0)
                    {
                        dividend._data.RemoveAt(dividend.Length - 1);
                    }
                }
                if (dividend[dividend.Length - 1] == 0)
                {
                    dividend._data.RemoveAt(dividend.Length - 1);

                    while (dividend[dividend.Length - 1] == 0)
                    {
                        quotient._exp--;
                        quotient._data.Add(0);
                        dividend._data.RemoveAt(dividend.Length - 1);
                        if (dividend.Length == 0)
                        {
                            break;
                        }
                    }
                    if (dividend.Length == 0)
                    {
                        break;
                    }
                    hump = false;
                }
                else
                {
                    hump = true;
                }

                if (quotient.Length == 82)
                {
                    c = 0;
                }
            }

            quotient._data.Reverse();
            quotient.Normalise();

            return(quotient);
        }
Exemple #3
0
 protected override BigNum Add(BigNum other)
 {
     return(BigFloat.Add(this, (BigFloat)other));
 }
Exemple #4
0
        public static BigFloat Multiply(BigFloat a, BigFloat b)
        {
            a = (BigFloat)a.Clone();
            b = (BigFloat)b.Clone();

            if(b.Length > a.Length) { // then switch them around
                BigFloat temp = a;
                a = b;
                b = temp;
            }

            BigFloat retval = new BigFloat();
            List<BigFloat> rows = new List<BigFloat>();

            retval._sign = a.Sign == b.Sign;
            retval._exp  = a._exp + b._exp;

            // for each digit in b
            for(int i=0;i<b.Length;i++) {

                BigFloat row = new BigFloat();
                row._exp = retval._exp;

                Int32 digit = 0, carry = 0;
                for(int exp=0;exp<i;exp++) row._data.Add( 0 ); // pad with zeros to the right

                for(int j=0;j<a.Length;j++) { // perform per-digit multiplication of a against b
                    digit = a[j] * b[i] + carry;
                    carry = digit / 10;
                    digit = digit % 10;
                    row._data.Add( (SByte)digit );
                }

                // reduce the carry
                while(carry > 0) {
                    digit = carry % 10;
                    carry = carry / 10;
                    row._data.Add( (SByte)digit );
                }

                rows.Add( row );

            }

            // sum the rows to give the result
            foreach(BigFloat row in rows) {
                retval  = (BigFloat)retval.Add(row);
            }

            retval.Normalise();

            return retval;
        }