Example #1
0
        /// <summary>
        /// Obtém o valor da aplicação sucessiva da operação soma ao mesmo valor tendo em conta que esta é associativa.
        /// </summary>
        /// <typeparam name="T">O tipo do valor.</typeparam>
        /// <typeparam name="Deg">O tipo que representa o número de vezes a adicionar.</typeparam>
        /// <typeparam name="D">A classe que define a soma.</typeparam>
        /// <param name="val">O valor.</param>
        /// <param name="pow">O expoente.</param>
        /// <param name="monoid">A classe que define a soma sobre o valor.</param>
        /// <param name="degreeIntegerNumber">O objecto responsável pelas operaçóes sobre o grau.</param>
        /// <returns>A potência do valor.</returns>
        /// <exception cref="MathematicsException">
        /// Se o monóide ou o objecto responsável pelas operações sobre inteiros forem nulos ou o expoente
        /// for negativo.
        /// </exception>
        public static T AddPower <T, Deg, D>(
            T val,
            Deg pow,
            D monoid,
            IIntegerNumber <Deg> degreeIntegerNumber)
            where D : IMonoid <T>
        {
            if (monoid == null)
            {
                throw new MathematicsException("Parameter multiplier can't be null.");
            }
            else if (degreeIntegerNumber == null)
            {
                throw new MathematicsException("Parameter degreeIntegerNumber can't be null.");
            }
            else if (degreeIntegerNumber.Compare(pow, degreeIntegerNumber.AdditiveUnity) < 0)
            {
                throw new MathematicsException("Can't computer the powers with negative expoents.");
            }
            else
            {
                var result   = monoid.AdditiveUnity;
                var innerPow = pow;
                var innerVal = val;
                var n        = degreeIntegerNumber.MapFrom(2);
                if (degreeIntegerNumber.Compare(innerPow, degreeIntegerNumber.AdditiveUnity) > 0)
                {
                    var degreeQuotientAndRemainder = degreeIntegerNumber.GetQuotientAndRemainder(
                        innerPow,
                        n);
                    if (degreeIntegerNumber.IsMultiplicativeUnity(degreeQuotientAndRemainder.Remainder))
                    {
                        result = monoid.Add(result, innerVal);
                    }

                    innerPow = degreeIntegerNumber.Multiply(innerPow, n);
                    while (degreeIntegerNumber.Compare(innerPow, degreeIntegerNumber.AdditiveUnity) > 0)
                    {
                        innerVal = monoid.Add(innerVal, innerVal);
                        degreeQuotientAndRemainder = degreeIntegerNumber.GetQuotientAndRemainder(
                            innerPow,
                            n);
                        if (degreeIntegerNumber.IsMultiplicativeUnity(degreeQuotientAndRemainder.Remainder))
                        {
                            result = monoid.Add(result, innerVal);
                        }

                        innerPow = degreeIntegerNumber.Multiply(innerPow, n);
                    }
                }

                return(result);
            }
        }
Example #2
0
        /// <summary>
        /// Obtém a potência de um valor.
        /// </summary>
        /// <typeparam name="T">O tipo do valor.</typeparam>
        /// <typeparam name="Deg">O tipo de classe que define os graus.</typeparam>
        /// <typeparam name="D">O tipo da classe que define a multiplicação.</typeparam>
        /// <param name="val">O valor.</param>
        /// <param name="pow">O expoente.</param>
        /// <param name="domain">O domínio responsável pelas operações sobre os valores.</param>
        /// <param name="integerNumber">A classe que define as operações sobre números inteiros.</param>
        /// <returns>A potência do valor.</returns>
        /// <exception cref="MathematicsException">
        /// Se o domínio ou o objecto que define operações sobre os inteiros forem nulos ou o expoente for negativo.
        /// </exception>
        public static T Power <T, Deg, D>(T val, Deg pow, D domain, IIntegerNumber <Deg> integerNumber)
            where D : IMultiplication <T>
        {
            if (integerNumber == null)
            {
                throw new MathematicsException("Parameter integerNumber can't be null.");
            }
            else if (domain == null)
            {
                throw new MathematicsException("Parameter domain can't be null.");
            }
            else if (integerNumber.Compare(pow, integerNumber.AdditiveUnity) < 0)
            {
                throw new MathematicsException("Can't computer the powers with negative expoents.");
            }
            else
            {
                var result   = domain.MultiplicativeUnity;
                var innerPow = pow;
                var innerVal = val;
                var two      = integerNumber.Successor(integerNumber.MultiplicativeUnity);
                if (integerNumber.Compare(innerPow, integerNumber.AdditiveUnity) > 0)
                {
                    var remQuo = integerNumber.GetQuotientAndRemainder(innerPow, two);
                    if (integerNumber.IsMultiplicativeUnity(remQuo.Remainder))
                    {
                        result = domain.Multiply(result, innerVal);
                    }

                    innerPow = remQuo.Quotient;
                    while (integerNumber.Compare(innerPow, integerNumber.AdditiveUnity) > 0)
                    {
                        innerVal = domain.Multiply(innerVal, innerVal);
                        remQuo   = integerNumber.GetQuotientAndRemainder(innerPow, two);
                        if (integerNumber.IsMultiplicativeUnity(remQuo.Remainder))
                        {
                            result = domain.Multiply(result, innerVal);
                        }

                        innerPow = remQuo.Quotient;
                    }
                }

                return(result);
            }
        }