User Tag List

Показано с 1 по 10 из 30

Тема: Квадратный корень

Древовидный режим

Предыдущее сообщение Предыдущее сообщение   Следующее сообщение Следующее сообщение
  1. #30

    Регистрация
    18.02.2005
    Адрес
    Набережные Челны
    Сообщений
    1,574
    Спасибо Благодарностей отдано 
    0
    Спасибо Благодарностей получено 
    3
    Поблагодарили
    2 сообщений
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от 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. для упрощения понимания алгоритма я не заменял вычитание сложением, что, однако, возможно, и несколько ускорит вычисление.
    Последний раз редактировалось GriV; 25.03.2012 в 11:12.
    Биты рулят лучше байтов, байты рулят шустрее!
    View, Звук, Цвет

Информация о теме

Пользователи, просматривающие эту тему

Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •