Вычисление целочисленного квадратного корня / Хабр
palukeВремя на прочтение 2 мин
Количество просмотров11K
Математика *
Возникла нужда проверить, является ли целое число квадратом, и если да, то вычислить корень. Причем хочется сделать это в целочисленной арифметике. Понятно, что можно реализовать метод Ньютона в целых числах, но он требует деления на каждом шаге. А нельзя ли по другому? Найти квадратный корень по модулю степени двойки, и проверить, а не будет ли он обычным квадратным корнем.
Можно ограничиться нечетными числами: для четного числа, если количество нулевых младших разрядов нечетно, то корня нет, а если четно, то можно сдвинуть число вправо, посчитать корень от нечетного, и сдвинуть обратно влево на половину от первоначального количества нулевых бит.
Для нечетного N и 2k, k > 3, если N ≡ 1 mod 8, то есть 4 разных корня по модулю 2k, а иначе корней нет. Нам нужен наименьший из этих четырех корней x. При этом другие три корня это 2k — x, 2k-1 + x и 2k — 2k-1 — x
Хочется что-то подобное вычислению обратного по модулю 2k — удваивая количество верных бит за итерацию.
Пусть у нас уже есть корень x0 из N по модулю 2k: N — x02 = 2ka
И мы хотим найти x1 = x0 + 2k-1y, такое чтобы в N — x12 было больше младших нулевых бит.
N — (x0 + 2k-1y)2 = 2ka — 2kx0 * y — 22k-2y2
Поделим на 2k: a — x0 * y — 2k-2y2
И приравняем к 0 по модулю 2
Получилии x1 = x0 + 2k-1a * (x0-1 mod 2k-2)
И окончательно x1 = x0 + (N — x02)/2 * (x0-1 mod 2k-2)
Из k бит на следующей итерации получится 2(k-1) бит. Параллельно считаем на каждой итерации обратное к корню.
Тестовый код:
uint8_t sqr16(uint16_t n) { if (n % 8 != 1) return 0; uint16_t sqr = (n + 1) / 2; //4 bit uint16_t inv = 2 - sqr; sqr += inv * (n-sqr*sqr)/2; //6 bit inv *= 2 - sqr * inv; sqr += inv * (n-sqr*sqr)/2; //10 bit //inv *= 2 - sqr * inv; if (sqr & 256) sqr = 0u - sqr; sqr = (uint8_t)sqr; // lowest root if (n == sqr*sqr) return sqr; return 0; }
Добавив пару итераций, получим корень из uint_64
Теги:
- теория чисел
- квадратный корень
Хабы:
- Математика
Всего голосов 29: ↑24 и ↓5 +19
Комментарии 13
@paluke
Пользователь
Комментарии Комментарии 13
3-8 9 Оценить квадратный корень из 12 10 Оценить квадратный корень из 20 11 Оценить квадратный корень из 50 94 18 Оценить квадратный корень из 45 19 Оценить квадратный корень из 32 20 Оценить квадратный корень из 18 92Чему равен квадратный корень из \\[2\\] в степени \\[2\\] ?
Последняя обновленная дата: 19 февраля 2023 г.
•
Всего просмотров: 206,4K
•
Просмотры сегодня: 3,93K
. Веркция
.
.
. довольно легко решить, если мы четко понимаем ключевые понятия, лежащие в основе данного вопроса. В таких задачах в первую очередь необходимо теоретическую постановку задачи преобразовать в математическую форму, а затем решить ее в соответствии с нашим требованием. Чтобы эффективно решить эту проблему, нам нужно иметь четкое представление о таких главах, как сурды и квадратные корни чисел. В этой конкретной задаче нам нужно найти квадратный корень из заданного числа. Общее представление квадратного корня любого числа ‘n’ имеет форму \[\sqrt{n}\] . Здесь, согласно постановке задачи, заданное число описывается как \[2\] в степени \[2\] , что математически представляется как \[{{2}^{2}}\].