Вот и пытаюсь ее найти. Помню, что-то вроде S = sqrt(x) + 10^((n-1)/2), но скорее всего ошибаюсь. На википелии статью про таблицы удалили по причине «нет значимости»
Линейки не застал, но Брадисом пользовался. В 2009 здесь уже был топик про таблицы с еще меньшим смыслом, чем мой. Раз топик еще живой, значит правила не нарушает. Что-то не так?
В соседнем топике я немного осветил тему что сейчас мучаю. Суть в том, чтобы написать интовый sqrt, который будет работать быстрее, чем ассемблерный fsqrt, который стоит внутри math.h/sqrt(double). Ну можете считать это моим бзиком, но я хочу из всех своих вычислений выкинуть float'ы.
На данный момент у меня такие данные - есть функция, в которой один раз вызывается sqrt и делаются некоторые вычисления. Она дергается 100 000 раз и засекается время. На math.h/sqrt это дело занимает 6.4 секунды. На моих различных реализациях по-разному. Тут типа табличка, с моими «пометками». Как видите, я пробовал все методы, которые мог найти. Минимальное время, к которому я подобрался это 7.6 (в табличке 7.7, я уже несколько коэффициенты успел улучшить).
Один из методов - это массив [0..MAX_UINT16-1], в котором содержатся квадраты значений i-счетчика. Занимает 256 кб в памяти, чем мне и не нравится. Суть в том, что после получения входного значения оно ищется в массиве а на выход выдается i, что и является ответом. 65536 ячеек дают 15 итераций на двоичном поиске и это очень много (в табличке это tables), если делать отсекание по первому биту и преустанавливать рамки, то это чуть быстрее (tables1lvl).
Теперь я хочу попробовать метод без поиска - строю в памяти (предварительно) таблицы брадиса - 256 х (16 + 16) это 32 КБ памяти, что гораздо меньше 256 и что я уже считаю приемлемым (хотя все равно введу функцию, чтобы инициализировать матблок по запросу, а без инициализации указатели на функции выставлять на более медленные варианты (указатели - это чтобы в каждую функцию не ставить условие на флаг - медленнее). Так вот - пришло число, лезем в таблицу, в которой не дробные значения, а так, как у нас максимум ответа будет 65536, то в таблице будут значения размером в 4 шестнадцатиричныйх разрядов (гм, т.е. можно тогда не 4 байта на число, а 2, с выключением выравнивания это всего 16 КБ, лол. Но тут надо скорость мерять). Так вот, получается, что вычисление корня сведется к:
0. С пустой функцией выполнение занимает 2.4 секунды времени на 100 000 итерациях.
1. Получение самого левого установленного бита в числе (через таблицы это 3.02 с)
2. Дальше мы сдвигаем значение на n-8 бит, чтобы получить самый левый байт.
3. Смотрим в таблице значение по байту и первой тетрадой, например это будет 12[.]345 (точку нарисовал условно, там будет целое)
4. Смотрим вторую тетраду после полученного байта и берем поправку (опять таки - прямой доступ к таблице - почти ноль.
5. Сносим влево на (m >> 1), где m - первоначальная позиция самого левого установленного бита.
Корень получен. В теории быстрее, чем что-то другое, потому что нет никаких итераций. Возможно я сейчас неправильно посчитал разряды и я таким образом недосчитался целого байта точности конечного результата. Но согласитесь, что если корень найден с точностью +-128, то найти оставшееся можно за пару шагов (еще не придумал, как, но все же)
Уже видел в виде разобранной статьи на русском. То, что описано в pdf - гогно, по причине того, что они, используя алгоритм Герона делают всего 2 итерации, а по хорошему там нужен while ([xn+1] - [xn]).
Не там ты оптимизируешь.
А я иду по порядку. И когда вижу функцию, которая в продакшене может вызываться 1280х800х60 раз в секунду - оптимизирую. Проблемы?
PS: Таблицы Брадиса — это тоже только апроксимизация.
Значит так. Старшие биты результата берёшь из заранее посчитанной таблицы. Получишь некоторое приближение. Потом это приближение улучшаешь методом Ньютона. Обычно достаточно 1-2 итерации, так как для квадратного корня он сходится с квадратичной скоростью. Вот пример для ардуины: https://github.com/Shulyaka/quadro/blob/master/fplib.h
Старшие биты результата берёшь из заранее посчитанной таблицы. Получишь некоторое приближение.
Уже. Надо будет не только Ньютоном проверить. Просто есть мысли просчитать таблицу поправок (как у Брадиса) и применять их же. В общем попробую оба метода.
Герон - это тот же Ньютон. 32 итерации - эта какая-то неправильная квадратичная сходимость. Каждая итерация удваивает число верных разрядов. Начав с 8, через 2 итерации их будет никак не меньше 32.