예제 #1
0
            /// <summary>
            /// Returns the integer part of the square root
            /// of the number.
            /// </summary>
            /// <remarks>This method works only for integer numeric types.</remarks>
            /// <param name="number">A strictly positive number for which the integer part of its square root is to be found.</param>
            /// <returns>The integer part of the square root of the <paramref name="number"/>.</returns>
            public static LongInt <B> SquareRootInteger(LongInt <B> number)
            {
                Contract.Requires <ArgumentNullException>(number != null, "number");
                Contract.Requires <ArgumentOutOfRangeException>(number > 0);

                LongInt <B> firstEstimate = number;

                // Имеет смысл находить лучшее, чем само число,
                // первое приближение, только в том случае,
                // если число имеет длину более 1.

                if (number.Length > 1)
                {
                    // Для курсача - доказать, что это хуже, чем то, что незакомментировано
                    //
                    // firstEstimate = LongInt<B>.CreatePowerOfBase((number.Length + 1) / 2);

                    if (!BASE_IS_FULL_SQUARE || number.Length % 2 == 0)
                    {
                        firstEstimate = LongInt <B> .CreatePowerOfBase((number.Length + 1) / 2);
                    }
                    else
                    {
                        firstEstimate = LongInt <B> .CreatePowerOfBase(number.Length / 2);

                        firstEstimate[firstEstimate.Length - 1] = LongInt <B> .Helper.BASE_SQRT_FLOOR;
                    }
                }

                return
                    (WhiteMath <LongInt <B>, CalcLongInt <B> > .SquareRootInteger(number, firstEstimate));
            }
예제 #2
0
        /// <summary>
        /// Returns the next non-negative <c>LongInt&lt;<typeparamref name="B"/>&gt;</c>
        /// number which is less than <paramref name="maxExclusive"/>.
        /// </summary>
        /// <param name="maxExclusive">The upper exclusive bound of generated numbers.</param>
        /// <returns>
        /// A non-negative <c>LongInt&lt;<typeparamref name="B"/>&gt;</c> number which
        /// is less than <paramref name="maxExclusive"/>.
        /// </returns>
        public LongInt <B> Next(LongInt <B> maxExclusive)
        {
            Contract.Requires <ArgumentNullException>(maxExclusive != null, "maxExclusive");
            Contract.Requires <ArgumentOutOfRangeException>(maxExclusive > 0, "The maximum exclusive bound should be a positive number.");

            LongInt <B> basePowered = LongInt <B> .CreatePowerOfBase(maxExclusive.Length);

            LongInt <B> upperBound;

            if (this.lastMaxExclusive != maxExclusive)
            {
                // Мы будем генерировать ВСЕ цифры от 0 до BASE - 1.
                // НО:
                // Мы отбрасываем верхнюю границу, где приведение по модулю maxExclusive
                // даст нам лишнюю неравномерность.
                // Мы можем использовать только интервал, содержащий целое число чисел maxExclusive.
                // Тогда спокойно приводим по модулю и наслаждаемся равномерностью.

                // Например, если мы генерируем цифирки по основанию 10, и хотим число от [0; 12),
                // то нам нужно отбрасывать начиная с floor(10^2 / 12) * 12 = 96.

                upperBound = Max_BinarySearch((LongInt <B>) 1, LongInt <B> .BASE, (res => LongInt <B> .Helper.MultiplyFFTComplex(res, maxExclusive) <= basePowered)) * maxExclusive;

                // upperBound = multiplication(basePowered / maxExclusive, maxExclusive);

                this.lastMaxExclusive = maxExclusive;
                this.lastBound        = upperBound;
            }
            else
            {
                upperBound = this.lastBound;
            }

            LongInt <B> result = new LongInt <B>();

REPEAT:

            result.Digits.Clear();

            for (int i = 0; i < maxExclusive.Length; i++)
            {
                result.Digits.Add(intGenerator.Next(0, LongInt <B> .BASE));
            }

            result.DealWithZeroes();

            if (result >= upperBound)
            {
                ++TotalRejected;
                goto REPEAT;
            }

            // Возвращаем остаток от деления.

            // return result % maxExclusive;

            LongInt <B> divisionResult = Max_BinarySearch((LongInt <B>) 0, LongInt <B> .BASE, (res => LongInt <B> .Helper.MultiplyFFTComplex(res, maxExclusive) <= result));

            return(result - LongInt <B> .Helper.MultiplyFFTComplex(divisionResult, maxExclusive));
        }
예제 #3
0
        /// <summary>
        /// Returns the next non-negative <c>LongInt&lt;<typeparamref name="B"/>&gt;</c>
        /// number which is less than <paramref name="maxExclusive"/>.
        /// </summary>
        /// <param name="maxExclusive">The upper exclusive bound of generated numbers.</param>
        /// <returns>
        /// A non-negative <c>LongInt&lt;<typeparamref name="B"/>&gt;</c> number which
        /// is less than <paramref name="maxExclusive"/>.
        /// </returns>
        public LongInt <B> Next(LongInt <B> maxExclusive)
        {
            Contract.Requires <ArgumentNullException>(maxExclusive != null, "maxExclusive");
            Contract.Requires <ArgumentOutOfRangeException>(maxExclusive > 0, "The maximum exclusive bound should be a positive number.");

            // Мы будем генерировать ВСЕ цифры от 0 до BASE - 1.
            // НО:
            // Мы отбрасываем верхнюю границу, где приведение по модулю maxExclusive
            // даст нам лишнюю неравномерность.
            // Мы можем использовать только интервал, содержащий целое число чисел maxExclusive.
            // Тогда спокойно приводим по модулю и наслаждаемся равномерностью.

            // Например, если мы генерируем цифирки по основанию 10, и хотим число от [0; 12),
            // то нам нужно отбрасывать начиная с floor(10^2 / 12) * 12 = 96.

            LongInt <B> upperBound = (LongInt <B> .CreatePowerOfBase(maxExclusive.Length) / maxExclusive) * maxExclusive;

            LongInt <B> result = new LongInt <B>();

REPEAT:

            result.Digits.Clear();

            for (int i = 0; i < maxExclusive.Length; i++)
            {
                result.Digits.Add(intGenerator.Next(0, LongInt <B> .BASE));
            }

            result.DealWithZeroes();

            if (result >= upperBound)
            {
                ++TotalRejected;
                goto REPEAT;
            }

            return(result % maxExclusive);
        }