Русская Википедия:Целочисленный квадратный корень

Материал из Онлайн справочника
Перейти к навигацииПерейти к поиску

Целочисленный квадратный корень (isqrt) натурального числа n — это положительное число m, которое равно наибольшему целому числу, меньшему либо равному квадратному корню из n,

<math>\mbox{isqrt}( n ) = \lfloor \sqrt n \rfloor.</math>

Например, <math>\mbox{isqrt}(27) = 5</math> поскольку <math>5^2 = 25 < 27</math> и <math>6^2 = 36 > 27</math>.

Алгоритм

Одним из путей вычисления <math>\sqrt{n}</math> и <math>\mbox{isqrt}( n )</math> — использование метода Ньютона для поиска решения уравнения <math>x^{2} - n = 0</math>, используя итеративную формулу[1][2]

<math>{x}_{k+1} = \frac{1}{2}\left(x_k + \frac{ n }{x_k}\right), \quad k \ge 0, \quad x_0 > 0.</math>

Последовательность <math>\{ x_k \}</math> сходится квадратично к <math>\sqrt{n}</math> при <math>k\to \infty</math>[3]. Можно доказать, что если <math>x_{0} = n</math> выбрано в качестве начального значения, можно останавливаться, как только

<math>| x_{k+1}-x_{k}| < 1</math>,

чтобы обеспечить, что <math>\lfloor x_{k+1} \rfloor=\lfloor \sqrt n \rfloor.</math>

Использование только целочисленного деления

Для вычисления <math>\lfloor \sqrt n \rfloor</math> для очень больших целых чисел n можно использовать частное деления с остатком при обеих операциях деления. Преимуществом является использование только целых чисел для каждого промежуточного значения, что освобождает от использования представления чисел в виде чисел с плавающей запятой. Это эквивалентно использованию итеративной формулы

<math>{x}_{k+1} = \left\lfloor \frac{1}{2}\left(x_k + \left\lfloor \frac{ n }{x_k} \right\rfloor \right) \right\rfloor, \quad k \ge 0, \quad x_0 > 0, \quad x_0 \in \mathbb{Z}.</math>

Основываясь на факте, что

<math>\left\lfloor \frac{1}{2}\left(x_k + \left\lfloor \frac{ n }{x_k} \right\rfloor \right) \right\rfloor = \left\lfloor \frac{1}{2}\left(x_k + \frac{ n }{x_k} \right) \right\rfloor,</math>

можно показать, что последовательность достигает <math>\lfloor \sqrt n \rfloor</math> за конечное число итераций [4].

Однако <math>\lfloor \sqrt n \rfloor</math> не обязательно будет неподвижной точкой итеративной формулы, приведённой выше. Можно показать, что <math>\lfloor \sqrt n \rfloor</math> будет неподвижной точкой тогда и только тогда, когда <math>n + 1</math> не является полным квадратом. Если <math>n + 1</math> является полным квадратом, последовательность не сходится, а переходит в цикл длины два, поочерёдно меняя <math>\lfloor \sqrt n \rfloor</math> и <math>\lfloor \sqrt n \rfloor + 1</math>. Для прекращения работы достаточно проверить, что либо последовательность сходится (повторение предыдущего значения), либо что следующее значение ровно на единицу больше текущего, в последнем случае новое значение отбрасывается.

Используя битовые операции

Если * означает умножение, << означает сдвиг влево, а >> — логический сдвиг вправо, рекурсивный алгоритм поиска целочисленного квадратного корня из любого натурального числа следующий:

function integerSqrt(n):
    if n < 0:
        error "integerSqrt работает только с неотрицательным входом"
    else if n < 2:
        return n
    else:
        smallCandidate = integerSqrt(n >> 2) << 1
        largeCandidate = smallCandidate + 1
        if largeCandidate*largeCandidate > n:
            return smallCandidate
        else:
            return largeCandidate

Или итерации вместо рекурсии:

function integerSqrt(n):
    if n < 0:
        error "integerSqrt работает только с неотрицательным входом"     
    # Находим наибольший сдвиг.
    shift = 2
    nShifted = n >> shift
    while nShifted ≠ 0 and nShifted ≠ n:
        shift = shift + 2
        nShifted = n >> shift
    shift = shift - 2
    
    # Находим цифры результата.
    result = 0
    while shift ≥ 0:
        result = result << 1
        candidateResult = result + 1
        if candidateResult*candidateResult ≤ n >> shift:
            result = candidateResult
        shift = shift - 2
   
    return result

Расчётная область

Хотя <math>\sqrt{n}</math> является иррациональным числом для большинства значений <math>n</math>, последовательность <math>\{ x_k \}</math> содержит только рациональные члены, если <math> x_0 </math> рационально. Таким образом, используя этот метод, нет необходимости выходить за пределы поля рациональных чисел, чтобы вычислить <math>\mbox{isqrt}( n )</math>, что имеет некоторое теоретическое преимущество.

Критерий остановки

Можно показать, что <math>c=1</math> является наибольшим числом для критерия остановки

<math>|x_{k+1} - x_{k}| < c\ </math>,

который обеспечивает, что <math>\lfloor x_{k+1} \rfloor=\lfloor \sqrt n \rfloor</math> в вышеприведённом алгоритме.

В приложениях, использующих отличные от рациональных чисел форматы (например, плавающую запятую), константу остановки следует выбрать меньшей единицы, чтобы избежать ошибок округления.

См. также

Примечания

Шаблон:Примечания

Ссылки

Шаблон:Rq Шаблон:Теоретико-числовые алгоритмы

  1. Метод называется иногда «вавилонским»
  2. Fred Akalin, Computing the Integer Square Root, 2014
  3. S. G. Johnson, MIT Course 18.335, Square Roots via Newton’s Method, February 4, 2015
  4. Шаблон:Книга