/// <summary>
        /// Divides <c>this</c> by <c>b</c> and stores the result in a new PolynomialGF2n[2], quotient in result[0] and remainder in result[1]
        /// </summary>
        ///
        /// <param name="B">The divisor</param>
        ///
        /// <returns>Retuens the quotient and remainder of <c>this</c> / <c>b</c></returns>
        public GF2nPolynomial[] Divide(GF2nPolynomial B)
        {
            GF2nPolynomial[] result = new GF2nPolynomial[2];
            GF2nPolynomial   a      = new GF2nPolynomial(this);

            a.Shrink();
            GF2nPolynomial shift;
            GF2nElement    factor;
            int            bDegree = B.Degree;
            GF2nElement    inv     = (GF2nElement)B._coeff[bDegree].Invert();

            if (a.Degree < bDegree)
            {
                result[0] = new GF2nPolynomial(this);
                result[0].AssignZeroToElements();
                result[0].Shrink();
                result[1] = new GF2nPolynomial(this);
                result[1].Shrink();
                return(result);
            }

            result[0] = new GF2nPolynomial(this);
            result[0].AssignZeroToElements();
            int i = a.Degree - bDegree;

            while (i >= 0)
            {
                factor = (GF2nElement)a._coeff[a.Degree].Multiply(inv);
                shift  = B.ScalarMultiply(factor);
                shift.ShiftThisLeft(i);
                a = a.Add(shift);
                a.Shrink();
                result[0]._coeff[i] = (GF2nElement)factor.Clone();
                i = a.Degree - bDegree;
            }

            result[1] = a;
            result[0].Shrink();
            return(result);
        }
        /// <summary>
        /// Computes the greatest common divisor of <c>this</c> and <c>g</c> and returns the result in a new PolynomialGF2n
        /// </summary>
        ///
        /// <param name="G">The GF2nPolynomial</param>
        ///
        /// <returns>Returns gcd(<c>this</c>, <c>g</c>)</returns>
        public GF2nPolynomial Gcd(GF2nPolynomial G)
        {
            GF2nPolynomial a = new GF2nPolynomial(this);
            GF2nPolynomial b = new GF2nPolynomial(G);

            a.Shrink();
            b.Shrink();
            GF2nPolynomial c;
            GF2nPolynomial result;
            GF2nElement    alpha;

            while (!b.IsZero())
            {
                c = a.Remainder(b);
                a = b;
                b = c;
            }

            alpha  = a._coeff[a.Degree];
            result = a.ScalarMultiply((GF2nElement)alpha.Invert());

            return(result);
        }
        /// <summary>
        /// Computes the greatest common divisor of <c>this</c> and <c>g</c> and returns the result in a new PolynomialGF2n
        /// </summary>
        /// 
        /// <param name="G">The GF2nPolynomial</param>
        /// 
        /// <returns>Returns gcd(<c>this</c>, <c>g</c>)</returns>
        public GF2nPolynomial Gcd(GF2nPolynomial G)
        {
            GF2nPolynomial a = new GF2nPolynomial(this);
            GF2nPolynomial b = new GF2nPolynomial(G);
            a.Shrink();
            b.Shrink();
            GF2nPolynomial c;
            GF2nPolynomial result;
            GF2nElement alpha;

            while (!b.IsZero())
            {
                c = a.Remainder(b);
                a = b;
                b = c;
            }

            alpha = a._coeff[a.Degree];
            result = a.ScalarMultiply((GF2nElement)alpha.Invert());

            return result;
        }
        /// <summary>
        /// Divides <c>this</c> by <c>b</c> and stores the result in a new PolynomialGF2n[2], quotient in result[0] and remainder in result[1]
        /// </summary>
        /// 
        /// <param name="B">The divisor</param>
        /// 
        /// <returns>Retuens the quotient and remainder of <c>this</c> / <c>b</c></returns>
        public GF2nPolynomial[] Divide(GF2nPolynomial B)
        {
            GF2nPolynomial[] result = new GF2nPolynomial[2];
            GF2nPolynomial a = new GF2nPolynomial(this);
            a.Shrink();
            GF2nPolynomial shift;
            GF2nElement factor;
            int bDegree = B.Degree;
            GF2nElement inv = (GF2nElement)B._coeff[bDegree].Invert();

            if (a.Degree < bDegree)
            {
                result[0] = new GF2nPolynomial(this);
                result[0].AssignZeroToElements();
                result[0].Shrink();
                result[1] = new GF2nPolynomial(this);
                result[1].Shrink();
                return result;
            }

            result[0] = new GF2nPolynomial(this);
            result[0].AssignZeroToElements();
            int i = a.Degree - bDegree;

            while (i >= 0)
            {
                factor = (GF2nElement)a._coeff[a.Degree].Multiply(inv);
                shift = B.ScalarMultiply(factor);
                shift.ShiftThisLeft(i);
                a = a.Add(shift);
                a.Shrink();
                result[0]._coeff[i] = (GF2nElement)factor.Clone();
                i = a.Degree - bDegree;
            }

            result[1] = a;
            result[0].Shrink();
            return result;
        }