|
алгоритмы извлечения квадратного корня |
|
|
|
Oct 13 2007, 07:10
|
Группа: Новичок
Сообщений: 10
Регистрация: 13-10-07
Пользователь №: 31 313

|
Подскажите пожалуйста ламеру какой-нибудь из алгоритмов извлечения квадратного корня (еще лучше привести соответствующий код на VHDL).
Сообщение отредактировал vovan1313 - Oct 13 2007, 07:12
|
|
|
|
|
Oct 13 2007, 09:15
|
Частый гость
 
Группа: Свой
Сообщений: 118
Регистрация: 1-10-07
Пользователь №: 30 988

|
Сам я VHDL не использую, но вот есть исходник из какой-то статьи в архивах.
--^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -- FILE: SQROOT.VHD -- PROJECT: Square Root Unit -- AUTHOR: Anatoli Sergyienko -- Email: aser@comsys.ntu-kpi.kiev.ua -- -- FUNCTION: - calculating the square root function -- from the positive integer data. -- CONSTRAINTS: the input data bit number is less than -- 2**(bit_num), where bit_num<28 is a generic value, -- the output data bit number is less than 2**(bit_num/2), -- respectively. Maximum error is equal to 1 l.s.b. --^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ library IEEE; use IEEE.STD_LOGIC_1164.all; use IEEE.STD_LOGIC_ARITH.all ;
entity SQRT is
generic (bit_num: integer:=16); port ( ARGUM: in INTEGER range 0 to 2**(bit_num)-1; SQRT: out INTEGER range 0 to 2**(bit_num/2)-1; RESET: in STD_LOGIC; CLK: in STD_LOGIC ); end SQRT;
architecture SQRT of SQRT is signal SQRT2 : INTEGER range 0 to 2**(bit_num/2)-1; signal arg: integer range 0 to 2**(bit_num)-1; function SQROOT(x1:integer; bn:integer) return integer is variable m,n,i : INTEGER range 0 to 15; variable a, b, x : INTEGER range 0 to 2**(bn+2)-1; variable y : INTEGER range 0 to 2**(bn+1)-1; begin y:=x1; x:=x1; m:=0; n:=bn/2; ROOT: for i in 1 to n loop a:=2**2*x; exit ROOT when a>=2**(bn+1); y:=2*y; x:=a; end loop; ROOT2:for i in 1 to n-1 loop m:=m+1; b:=x+x/2**m; a:=b+b/2**m; if a>=2**(bn+1) then x:=x; y:=y; else x:=a; y:=y+y/2**m; end if; end loop; y:=y+2**(n-1); return y/2**n; end; begin process(RESET,CLK,ARGUM) begin if RESET ='1' then ARG<=0; SQRT<=0; elsif CLK='1' and CLK'event then ARG<=ARGUM; SQRT<= SQROOT(ARG, bit_num); end if; end process; end SQRT;
|
|
|
|
|
Oct 15 2007, 05:36
|
Местный
  
Группа: Участник
Сообщений: 450
Регистрация: 21-12-06
Пользователь №: 23 757

|
Цитата(vovan1313 @ Oct 13 2007, 11:10)  Подскажите пожалуйста ламеру какой-нибудь из алгоритмов извлечения квадратного корня (еще лучше привести соответствующий код на VHDL). Когда то баловался... Xn+1=Xn+Y/Xn; Y - это то, из чего корень извлекают. X0 - скажем Y/2.
|
|
|
|
|
Oct 15 2007, 06:38
|
Участник

Группа: Новичок
Сообщений: 47
Регистрация: 26-05-06
Пользователь №: 17 478

|
Xn+1=(Xn+Y/Xn)/2; Y - это то, из чего корень извлекают. X0 - скажем Y/2. Формулу отAlex255 чуток поправил.
|
|
|
|
|
Oct 17 2007, 14:38
|
Группа: Новичок
Сообщений: 10
Регистрация: 13-10-07
Пользователь №: 31 313

|
Цитата(SergVZ @ Oct 15 2007, 10:38)  Xn+1=(Xn+Y/Xn)/2; Y - это то, из чего корень извлекают. X0 - скажем Y/2. Формулу отAlex255 чуток поправил. SergVZ, а сколько итераций надо сделать, чтобы точность была ну, хотя бы 5-10%?
|
|
|
|
|
Oct 18 2007, 14:40
|
Участник

Группа: Новичок
Сообщений: 47
Регистрация: 26-05-06
Пользователь №: 17 478

|
GetSmart, Вам похоже повезло с цифрами, возьмите для примера числа :100000 или 10е-6  vovan1313, Вы не указали диапозон аргумента и его тип. Попробуйте по-экспериментировать на калькуляторе число шагов с минимальным (если аргумент вещественный-наиболее его близким к нулю), несколько средних (по порядку) значениями и максимальным. Я с ПЛИСами не работал (Вы же просили верилоговский сырец дать)-тут совет не дам. Не забудьте проверить, что извлекаете корень из неотрицательного числа и сделать проверку на ноль, иначе Вам на "0" придеться делить. На процах (МК) , при юзаньи этого алгоритма ("Ньютона") я всегда число итераций ограничиваю сверху из значения, полученного на кулькуляторе +1, и сравниваю разность между значениями соседних иттераций, она (разность) по модулю больше абсолютной ошибки. Можете попробовать пару методов, на основе рядов Тейлора: F(X)=.. или F(X0+dX)= , число членов оценивайте по калькулятору, но тут не придется делить на добные числа.
|
|
|
|
|
Oct 18 2007, 18:12
|
Участник

Группа: Новичок
Сообщений: 47
Регистрация: 26-05-06
Пользователь №: 17 478

|
К сожалению, уже потерял право на релактирование своего поста. Ловите добавку к нему: Можно составить табличку: первые цифры(одна- две) аргумента-ответ, плюс поправка, наподобие таблиц Брадиса (ими раньше в школах пользовались).
|
|
|
|
|
Oct 19 2007, 12:38
|
Группа: Новичок
Сообщений: 10
Регистрация: 13-10-07
Пользователь №: 31 313

|
спасибо за помощь всем, кто ответил, попробую вспомнить численные методы решения уравнений для оценки погрешности
Сообщение отредактировал vovan1313 - Oct 19 2007, 12:38
|
|
|
|
|
Oct 5 2009, 12:45
|
Участник

Группа: Участник
Сообщений: 69
Регистрация: 28-10-05
Из: Харьков, ул. Героев труда.
Пользователь №: 10 213

|
Код /////////////////////////////////////////////////////////////////////////// // Carmack from ID Software's unusual square root routine for // the quake engine inline float q_sqrt(float number) { long i; float x, y; const float f = 1.5F; x = number * 0.5F; y = number; i = * (long*) &y; i = 0x5f3759df - (i >> 1); y = * (float * ) &i; y = y * (f - (x * y * y)); y = y * (f - (x * y * y)); return number *y; }
|
|
|
|
|
Oct 8 2009, 14:29
|

Гуру
     
Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954

|
Цитата(SergVZ @ Oct 15 2007, 09:38)  Xn+1=(Xn+Y/Xn)/2; Y - это то, из чего корень извлекают. X0 - скажем Y/2. Брать за Х0 число Y/2 - не самый лучший вариант... Когда-то давно самому пришлось писать функцию вычисления корня квадратного. Программулину ту что-то найти не удаётся... По-памяти: Если вспомнить, что вещественные числа в памяти хранятся в виде 2^N*M, то квадратный корень от числа будет равен 2^(N/2)*sqtr(M). Плохо то, что N может быть нечётным, да и корень от мантисы взять неоткуда... Но за X0 очень хорошо взять число хотя бы со степенью N/2, тем более, что получить его, обычно, очень просто - сдвигом вправо на 1 разряд. При этом получаем промежуточный результат с 1-2 верными первыми десятичными цифрами. Ну, а дальше - Ньютон: каждая итерация добавляет ещё 1-2 верные цифры. Правда, если итерация дала 2 верные цифры, то следующая скорее всего даст только одну. Для получения шести верных первых цифр всегда достаточно взять Х0 по правилу изложенному выше и сделать 3 итерации.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|