Ejemplo n.º 1
0
 protected override BigNum Multiply(BigNum multiplicand)
 {
     return(BigFloat.Multiply(this, (BigFloat)multiplicand));
 }
Ejemplo n.º 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);
        }
Ejemplo n.º 3
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;
        }