
Сообщение от
GriV
Вот посмотрел методом ряда вычисление, точное вычисление т.е.
Медленное, конечно, но может кому понадобится.
Виноват, невнимательно первую ссылку смотрел.
Там такое было, только гораздо более умно сделано.
---------- Post added at 10:10 ---------- Previous post was at 09:29 ----------
Подумав, сделал такой компромисс между скоростью и размером таблиц.
Всего таблица будет 768 байт.
Суть следующая.
Процедура вычисления корня медленна потому, что происходит небыстрое итеративное приближение к заданному значению.
Можно это приближение заменить табличным значением.
Т.е. используя значение старшего регистра hl (т.е. регистр h) можно определить наименьшее приближённое значение для начала итеративного поиска и затем уже доводить финальную часть "поиска" путем классического вычитания нечётного числа.
Конкретный пример.
Есть число 1761.
В этом случае старший байт будет 6. для этого значения выбирается базовое значение 1681 и значение вычисленное - 41. Тогда можно занести в вычитаемое 41*2+1=83 (путём банального add hl,hl, inc hl) и получить начальное нечётное число.
После этого вычитаем из 1761 значение 1681 получаем 80.
Пытаемя вычесть из остатка равному 80 полученное вычитаемое нечётное число 83 - не получается, т.о. счёт закончен, вычисленное целое значение корня - 41.
Т.е. счёт произошёл в 1 итерацию.
По этому примеру видно главная проблема методики: для числа в диапазоне 0-255 будет производится (для конкретно числа 255) аж 16 итераций.
Что технически можно решить заведением отдельной таблицы под эти 256 значений.
Для значений 256-511 остаётся всего 7 итераций, что для меня является терпимым. Чем выше значение корня, тем быстрее он будет вычисляться.
Код:
; hl — число для корня
ex de,hl ; нужно получить данные из таблицы
ld h,tab/256 ; загружаем адрес таблицы
ld l,d ; устанавливаем по старшему байту
ld c,(hl) ; загружаем базовое значение
inc h
ld b,(hl)
inc h
ld a,(hl) ; и значение корня для него
ld l,a
ld h,0 ; создаём нечётное вычитаемое число
add hl,hl
inc hl
ex de,hl
sbc hl,bc ; т.е. до этого делали add hl,hl то флаг переноса
; сброшен, вычитаем базовое число
sqr sbc hl,de ; собственно делаем счёт
inc de
inc de
inc a
jp nc,sqr
dec a ; возвращаем истиное значение корня
ret
; в А - полученное значение корня
---------- Post added at 10:14 ---------- Previous post was at 10:10 ----------
P.S. для упрощения понимания алгоритма я не заменял вычитание сложением, что, однако, возможно, и несколько ускорит вычисление.