Jump to content

Целочисленный квадратный корень

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

Например,

Вступительное замечание

[ редактировать ]

Позволять и быть неотрицательными целыми числами.

Алгоритмы вычисления ( десятичное представление ) работать вечно на каждом входе что не является идеальным квадратом . [примечание 1]

Алгоритмы, которые вычисляют не бегай вечно . Тем не менее, они способны вычислять с любой желаемой точностью .

Выбирайте любой и вычислить .

Например (установка ):

Сравните результаты с

Оказывается, что умножение входных данных на дает точность k десятичных цифр. [примечание 2]

Чтобы вычислить (полное) десятичное представление , можно выполнить бесконечное число раз, увеличивая по фактору на каждом проходе.

Предположим, что в следующей программе ( ) процедура уже определено и — ради аргумента — что все переменные могут содержать целые числа неограниченной величины.

Затем напечатает все десятичное представление . [примечание 3]

// Печатаем sqrt(y), не останавливаясь  void   sqrtForever  (  unsigned   int   y  )  { 	 unsigned   int   result   =   isqrt  (  y  ); 	 printf  (  "%d."  ,   результат  ); 	 // вывести результат, за которым следует десятичная точка 	 while   (  true  ) 	 // повторять вечно ... 	 { 		 y   =   y   *   100  ; 	 // теоретический пример: переполнение игнорируется 		 result   =   isqrt  (  y  ); 		 printf  (  "%d"  ,   результат   %   10  ); 	 // выводим последнюю цифру результата 	 }  } 

Вывод состоит в том, что алгоритмы, вычисляющие isqrt() вычислительно эквивалентны алгоритмам, которые вычисляют sqrt(). [1]

Основные алгоритмы

[ редактировать ]

Целый квадратный корень из неотрицательного целого числа можно определить как

Например, потому что .

[ редактировать ]

Следующие программы на языке C представляют собой простую реализацию.

// Целочисленный квадратный корень  // (с использованием линейного поиска по возрастанию)  unsigned   int   isqrt  (  unsigned   int   y  )  { 	 // начальное занижение, L <= isqrt(y) 	 unsigned   int   L   =   0  ; 	 в то время как   ((  L   +   1  )   *   (  L   +   1  )   <=   y  ) 		 L знак   равно   L   +   1  ; 	 вернуть   Л  ;  } 
// Целочисленный квадратный корень  // (с использованием линейного поиска по убыванию)  unsigned   int   isqrt  (  unsigned   int   y  )  { 	 // начальное завышение, isqrt(y) <= R 	 unsigned   int   R   =   y  ; 	 в то время как   (  р   *   р   >   y  ) 		 р   знак равно   р   -   1  ; 	 вернуть   Р  ;  } 

Линейный поиск с использованием сложения

[ редактировать ]

В приведенной выше программе (линейный поиск по возрастанию) можно заменить умножение сложением, используя эквивалентность

// Целочисленный квадратный корень  // (линейный поиск, по возрастанию) с использованием сложения  unsigned   int   isqrt  (  unsigned   int   y  )  { 	 unsigned   int   L   =   0  ; 	 беззнаковое   целое   число   =   1  ; 	 беззнаковое   целое число   d   =   3  ; 	 в то время как   (  а   <=   y  ) 	 { 		 а знак   равно   а   +   d  ; 	 // (а + 1) ^ 2 		 d   =   d   +   2  ; 		 Л   =   Л   +   1  ; 	 } 	 Вернуть   Л  ;  } 
[ редактировать ]

Линейный поиск последовательно проверяет каждое значение, пока не достигнет наименьшего. где .

Ускорение достигается за счет использования вместо этого двоичного поиска . Следующая C-программа является реализацией.

// Целочисленный квадратный корень (с использованием двоичного поиска)  unsigned   int   isqrt  (  unsigned   int   y  )  { 	 unsigned   int   L   =   0  ; 	 беззнаковый   интервал   M  ; 	 беззнаковый   int   R   =   y   +   1  ;      в то время как   (  L   !=   р   -   1  )      {          M   знак равно   (  L   +   р  )   /   2  ; 		 если   (  M   *   M   <=   y  ) 			 L знак   равно   M  ; 		 иначе 			 Р   =   М  ; 	 }      Вернуть   Л  ;  } 

Численный пример

Например, если вычислить используя бинарный поиск, можно получить последовательность

Это вычисление занимает 21 итерацию, тогда как линейный поиск (по возрастанию, начиная с ) нужно 1414 шагов.

Алгоритм с использованием метода Ньютона

[ редактировать ]

Один из способов расчета и заключается в использовании метода Герона , который является частным случаем метода Ньютона , для нахождения решения уравнения , давая итерационную формулу

Последовательность сходится квадратично к как .

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

[ редактировать ]

Можно доказать [ нужна ссылка ] что — максимально возможное число, для которого критерий остановки обеспечивает в алгоритме выше.

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

Область вычислений

[ редактировать ]

Хотя иррационально для многих , последовательность содержит только рациональные члены, когда является рациональным. Таким образом, при этом методе нет необходимости выходить из поля рациональных чисел, чтобы вычислить , факт, который имеет некоторые теоретические преимущества.

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

[ редактировать ]

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

Используя тот факт, что

можно показать, что это достигнет за конечное число итераций.

В оригинальной версии есть для , и для . Итак, в целочисленной версии имеем и до окончательного решения достигается. Для окончательного решения , у одного есть и , поэтому критерием остановки является .

Однако, не обязательно является фиксированной точкой приведенной выше итерационной формулы. Действительно, можно показать, что является фиксированной точкой тогда и только тогда, когда не является идеальным квадратом. Если является идеальным квадратом, последовательность завершается циклом второго периода между и вместо того, чтобы сходиться.

Пример реализации на C

[ редактировать ]
// Квадратный корень из целого числа  unsigned   int   int_sqrt  (  unsigned   int   s  )  { 	 // Ноль дает ноль      // Единица дает единицу 	 if   (  s   <=   1  )  		 return   s  ;      // Начальная оценка (должна быть слишком высокой) 	 unsigned   int   x0   =   s   /   2  ; 	 // Обновляем 	 unsigned   int   x1   =   (  x0   +   s   /   x0  )   /   2  ; 	 while   (  x1   <   x0  ) 	 // Проверка границ 	 { 		 x0   =   x1  ; 		 х1   знак равно   (  х0   +   s   /   х0  )   /   2  ; 	 } 			 Вернуть   х0  ;  } 

Численный пример

[ редактировать ]

Например, если вычислить целый квадратный корень из 2000000 , используя приведенный выше алгоритм, можно получить последовательность Всего необходимо 13 итераций. Хотя метод Герона сходится квадратично близко к решению, в начале достигается точность менее одного бита на итерацию. Это означает, что выбор начальной оценки имеет решающее значение для производительности алгоритма.

быстрое вычисление целой части двоичного логарифма или длины бита (например, Когда доступно std::bit_width в C++20 ), лучше начать с что является наименьшей степенью двух больше, чем . В примере целочисленного квадратного корня из 2000000 , , , и результирующая последовательность В этом случае необходимо всего четыре шага итерации.

Поразрядный алгоритм

[ редактировать ]

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

Использование побитовых операций

[ редактировать ]

При работе с базой 2 выбор цифры упрощается до выбора между 0 («маленький кандидат») и 1 («большой кандидат»), а манипуляции с цифрами могут быть выражены с помощью операций двоичного сдвига. С * будучи умножением, << будучи левой сменой, и >> будучи логическим сдвигом вправо, рекурсивный алгоритм нахождения целого квадратного корня из любого натурального числа :

def   целое_sqrt  (  n  :   int  )   ->   int  :      утверждать   n   >=   0  ,   «sqrt работает только для неотрицательных входных данных»,      если   n   <   2  :          return   n      # Рекурсивный вызов:      small_cand   =   целое_sqrt  (  n   >>   2  )   <<   1      big_cand   =   small_cand   +   1      if   big_cand   *   big_cand   >   n  :          return   small_cand      else  :          return   big_cand  # эквивалентно:  def   целое_sqrt_iter  (  n  :   int  )   ->   int  :      утверждать   n   >=   0  ,   «sqrt работает только для неотрицательных входных данных»      , если   n   <   2  :          return   n      # Найти сумму сдвига. См. также [[найти первый набор]],      # сдвиг = ceil(log2(n) * 0,5) * 2 = ceil(ffs(n) * 0,5) * 2      сдвиг   =   2      while   (  n   >>   сдвиг  )   !=   0  :          сдвиг   +=   2      # Разворачиваем цикл установки битов.      result   =   0      whileshift   )   >=   0  :          result   =   result   <<   1          big_cand   =   (              result   +   1          if    что и result ^ 1 (xor), потому что последний бит всегда равен 0.          # То же ,   big_cand   *   big_cand   <=   n   >>   сдвиг  :              result   =   big_cand          сдвиг   -=   2      возвращает   результат 

Традиционные описания поразрядного алгоритма на бумаге включают в себя различные оптимизации, отсутствующие в приведенном выше коде, в частности, трюк предварительного вычитания квадрата предыдущих цифр, что делает ненужным общий шаг умножения. Пример см . в разделе «Методы вычисления квадратных корней § Двоичная система счисления (основание 2») . [2]

В языках программирования

[ редактировать ]

Некоторые языки программирования выделяют явную операцию для вычисления квадратного корня целого числа в дополнение к общему случаю или могут быть расширены с этой целью библиотеками.

См. также

[ редактировать ]

Примечания

[ редактировать ]
  1. ^ Квадратные корни идеальных квадратов (например, 0, 1, 4, 9, 16) являются целыми числами. Во всех остальных случаях квадратные корни натуральных чисел являются иррациональными числами.
  2. ^ Неудивительно, что повторное умножение на 100 является особенностью Джарвиса (2006).
  3. ^ Дробная часть квадратных корней из полных квадратов отображается как 000... .
  1. ^ см. « Методы вычисления квадратных корней ».
  2. ^ Ву, К. (июнь 1985 г.). «Квадратный корень по алгоритму счетов (в архиве)» . Архивировано из оригинала 06 марта 2012 г.
  3. ^ ЛиспВоркс Лтд. (1996). «CLHS: Функция SQRT, ISQRT» . www.lispworks.com .
  4. ^ Фонд программного обеспечения Python (2001). «Математические функции» . Документация стандартной библиотеки Python . (начиная с версии 3.8).
[ редактировать ]
Arc.Ask3.Ru: конец переведенного документа.
Arc.Ask3.Ru
Номер скриншота №: 6b907ce0cb7cc5f27e1974bc8cf59ced__1702438620
URL1:https://arc.ask3.ru/arc/aa/6b/ed/6b907ce0cb7cc5f27e1974bc8cf59ced.html
Заголовок, (Title) документа по адресу, URL1:
Integer square root - Wikipedia
Данный printscreen веб страницы (снимок веб страницы, скриншот веб страницы), визуально-программная копия документа расположенного по адресу URL1 и сохраненная в файл, имеет: квалифицированную, усовершенствованную (подтверждены: метки времени, валидность сертификата), открепленную ЭЦП (приложена к данному файлу), что может быть использовано для подтверждения содержания и факта существования документа в этот момент времени. Права на данный скриншот принадлежат администрации Ask3.ru, использование в качестве доказательства только с письменного разрешения правообладателя скриншота. Администрация Ask3.ru не несет ответственности за информацию размещенную на данном скриншоте. Права на прочие зарегистрированные элементы любого права, изображенные на снимках принадлежат их владельцам. Качество перевода предоставляется как есть. Любые претензии, иски не могут быть предъявлены. Если вы не согласны с любым пунктом перечисленным выше, вы не можете использовать данный сайт и информация размещенную на нем (сайте/странице), немедленно покиньте данный сайт. В случае нарушения любого пункта перечисленного выше, штраф 55! (Пятьдесят пять факториал, Денежную единицу (имеющую самостоятельную стоимость) можете выбрать самостоятельно, выплаичвается товарами в течение 7 дней с момента нарушения.)