реклама на сайте
подробности

 
 
> Очень нужна помощь в оптимизации алгоритма извлечения квадратного корня
Rostislav
сообщение Dec 4 2012, 22:16
Сообщение #1


Частый гость
**

Группа: Участник
Сообщений: 127
Регистрация: 6-07-08
Из: Москва
Пользователь №: 38 765



Ребята, всем привет! Помогите, пожалуйста оптимизировать алгоритм извлечения корня. А то что-то до фига получается циклов вычисления. Заранее огромное спасибо всем откликнувшимся!

Алгоритм простой, основан на методе последовательного приближения. Собственно вот он (без шелухи):

bprev:=bprev div 2;
if (b+bprev)*(b+bprev) > a then
b:=b-bprev
else
if (b+bprev)*(b+bprev) < a then
b:=b+bprev
else
выход;
повтор цикла....

Полный текст:

a:word;
b:word;
bprev:word;
cnt:word;

a:=strtoint(edit1.Text); // подкоренное выражение
b:=a; // в b хранится результат
bprev:=a;
cnt:=0;
while 1=1 do begin
cnt:=cnt+1; // Счетчик циклов
bprev:=bprev div 2;
if bprev=0 then begin
bprev:=1;
if ((b+1)*(b+1) > a) and ((b+0)*(b+0) < a) then break;
end;
if (b+bprev)*(b+bprev) > a then
b:=b-bprev
else
if (b+bprev)*(b+bprev) < a then
b:=b+bprev
else
break;
end;
b:=b+bprev;
Form1.Caption:='результат: '+inttostr(b)+' циклов: '+inttostr(cnt);

Результаты замера следующие:
sqr (1) - 2 цикла;
sqr (10) - 5 циклов;
sqr (100) - 5 циклов;
sqr (1000) - 13 циклов;
sqr (10000) - 38 циклов;
sqr (32000) - 73 цикла;
...

Алгоритм предложенный alexeyv:

i:=1; // результат в i
b:=1;
a:=10000; // подкоренное выражение
while 1=1 do begin
if (b > a) or (b = a) then break;
b:=b+2;
a:=a-b;
i:=i+1;
end;
caption:=inttostr(i);

sqr (10000) - 100 циклов.

Сообщение отредактировал Rostislav - Dec 5 2012, 07:35
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
ASN
сообщение Dec 20 2012, 14:38
Сообщение #2


Местный
***

Группа: Свой
Сообщений: 459
Регистрация: 15-07-04
Из: g.Penza
Пользователь №: 326



Rostislav
С какой практической точностью нужно вычислять выражение ?
На какой целевой платформе выполняется прикладная программа?
Если вычислительная система поддерживает вычисления с плавающей точкой , то лучше воспользоваться арифметическим сопроцессором (типа сопроцессора для i386) или специальными командами самого процессора (как в TMS320C55).
Если требуется целочисленная арифметика, то проще и быстрее заранее вычисленной таблицы в памяти что-то предложить сложно.
Go to the top of the page
 
+Quote Post
Rostislav
сообщение Dec 20 2012, 20:46
Сообщение #3


Частый гость
**

Группа: Участник
Сообщений: 127
Регистрация: 6-07-08
Из: Москва
Пользователь №: 38 765



Цитата(ASN @ Dec 20 2012, 17:38) *
С какой практической точностью нужно вычислять выражение ?


Уважаемый ASN! Мне придумалась еще одна идея. Более простого алгоритма я придумать не смог (кстати, не понятно, почему этот вариант мне раньше не пришел в голову). Но все же отвечу на Ваши вопросы))

Меня интересует целочисленный результат.

Цитата(ASN @ Dec 20 2012, 17:38) *
На какой целевой платформе выполняется прикладная программа?
Если вычислительная система поддерживает вычисления с плавающей точкой , то лучше воспользоваться арифметическим сопроцессором (типа сопроцессора для i386) или специальными командами самого процессора (как в TMS320C55).


Меня интересовал вариант, который мог бы выполнятся на микроконтроллерах с простой архитектурой (типа PIC12).

Цитата(ASN @ Dec 20 2012, 17:38) *
Если требуется целочисленная арифметика, то проще и быстрее заранее вычисленной таблицы в памяти что-то предложить сложно.


Таблицы сразу не понравились. Для них нужна память.

----

Итак, мое заднее)))) предложение:

Код
  a : Word;  // подкоренное выражение
  b : Word;  // результат
  n : Byte;

  a := 121;
  b := 0;

  // начало
  for n := 15 downto 0 do   // Счет от 15 до 0   // 15 - разрядность подкоренного выражения (вернее N не 15, а N=15+1)
   begin
     if ((b + 1 shl n) * (b + 1 shl n) < a) or         // shl - побитовый сдвиг влево на n бит
        ((b + 1 shl n) * (b + 1 shl n) = a) then
      begin
        b := b + 1 shl n;
      end;
   end;
  // конец

  Form1.Caption := IntToStr (b);    // b = 11

  Циклов для 16-ти разрядного числа 16!!!
         для 32-х  разрядного числа 32!!!!!!


По-моему, получилось красиво))) Операции умножения можно заменить на бинарное сложение столбиком с предварительным смещением бит влево. Если более оптимального алгоритма наука)) еще не придумала, то тему можно закрывать. Теперь возьмусь за вычисление тригонометрических функций)))) Всем спасибо!!!!!

Сообщение отредактировал Rostislav - Dec 20 2012, 21:57
Go to the top of the page
 
+Quote Post
beaRTS
сообщение Dec 21 2012, 02:07
Сообщение #4


Местный
***

Группа: Участник
Сообщений: 211
Регистрация: 27-12-11
Из: Челябинск
Пользователь №: 69 111



Цитата(Rostislav @ Dec 21 2012, 00:46) *
[code] a : Word; // подкоренное выражение
b : Word; // результат
n : Byte;

a := 121;
b := 0;

// начало
for n := 15 downto 0 do // Счет от 15 до 0 // 15 - разрядность подкоренного выражения (вернее N не 15, а N=15+1)
begin
if ((b + 1 shl n) * (b + 1 shl n) < a) or // shl - побитовый сдвиг влево на n бит
((b + 1 shl n) * (b + 1 shl n) = a) then
begin
b := b + 1 shl n;
end;
end;
// конец

Form1.Caption := IntToStr (cool.gif; // b = 11
[code]

По-моему, получилось красиво)))


Может, я чего-то не понимаю... но в цикле for явно не красота красуется. Вы 5 раз вычисляете одно и тоже выражение b + 1 shl n !! Дык, зачем это делать?. один раз вычислите, присвойте результат какой-нибудь временной переменной и таскайте ее за собой везде. что-то типа:

for n := 15 downto 0 do // Счет от 15 до 0 // 15 - разрядность подкоренного выражения (вернее N не 15, а N=15+1)
begin
temp := b + 1 shl n;
if (temp * temp < a) or // А ТАК НЕЛЬЗЯ???? (temp * temp <= a )
(temp * temp = a) then
begin
b := temp
end;
end;
// конец

Сообщение отредактировал beaRTS - Dec 21 2012, 02:10


--------------------
"Об уме человека вернее судить по его вопросам, нежели по его ответам" (с)
Go to the top of the page
 
+Quote Post
Rostislav
сообщение Dec 21 2012, 05:56
Сообщение #5


Частый гость
**

Группа: Участник
Сообщений: 127
Регистрация: 6-07-08
Из: Москва
Пользователь №: 38 765



Цитата(beaRTS @ Dec 21 2012, 05:07) *
temp := b + 1 shl n;
if (temp * temp < a) or //А ТАК НЕЛЬЗЯ????


Да нее, Вы все правильно понимаете)))))))) Просто я не стал делать очевидное, то, что лежит на поверхности. Ну конечно же, мне известны некоторые трюки программирования. Умножение на 2 (и деление), например, легко можно заменить на побитовый сдвиг и т.п. А Ваш вариант оптимизации сделает, скорее всего, компилятор. Меня (и не только меня, наверное) больше всего интересовала суть. Суть я и изложил. Поэтому, спасибо Вам за участие и с наступающим Новым Годом!!!!!!!)))))))))

Сообщение отредактировал Rostislav - Dec 21 2012, 05:58
Go to the top of the page
 
+Quote Post
beaRTS
сообщение Dec 21 2012, 06:16
Сообщение #6


Местный
***

Группа: Участник
Сообщений: 211
Регистрация: 27-12-11
Из: Челябинск
Пользователь №: 69 111



Цитата(Rostislav @ Dec 21 2012, 08:56) *
Да нее, Вы все правильно понимаете)))))))) Просто я не стал делать очевидное, то, что лежит на поверхности. Ну конечно же, мне известны некоторые трюки программирования. Умножение на 2 (и деление), например, легко можно заменить на побитовый сдвиг и т.п. А Ваш вариант оптимизации сделает, скорее всего, компилятор. Меня (и не только меня, наверное) больше всего интересовала суть. Суть я и изложил. Поэтому, спасибо Вам за участие и с наступающим Новым Годом!!!!!!!)))))))))

а, ну тогда добро, добро. я тут тоже начал над своим вариантом извлечения корня биться. Ну как своим - комбинирую два метода. посмотрим что получится


--------------------
"Об уме человека вернее судить по его вопросам, нежели по его ответам" (с)
Go to the top of the page
 
+Quote Post
Rostislav
сообщение Dec 21 2012, 06:19
Сообщение #7


Частый гость
**

Группа: Участник
Сообщений: 127
Регистрация: 6-07-08
Из: Москва
Пользователь №: 38 765



Цитата(beaRTS @ Dec 21 2012, 09:16) *
а, ну тогда добро, добро. я тут тоже начал над своим вариантом извлечения корня биться. Ну как своим - комбинирую два метода. посмотрим что получится


Здорово!!!))) Выкладывайте Ваши идеи!!!!!! Очень интересно!!!)))

Сообщение отредактировал Rostislav - Dec 21 2012, 06:19
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- Rostislav   Очень нужна помощь в оптимизации алгоритма извлечения квадратного корня   Dec 4 2012, 22:16
- - alexeyv   Если нужна только целая часть квадратного корня, т...   Dec 5 2012, 03:37
|- - Rostislav   Цитата(alexeyv @ Dec 5 2012, 06:37) 1 = 1...   Dec 5 2012, 06:09
|- - Tanya   Цитата(Rostislav @ Dec 5 2012, 10:09) Заб...   Dec 5 2012, 06:28
- - Rostislav   Что забавляет? Все)) Магия чисел в особенности)) ...   Dec 5 2012, 06:55
|- - MrYuran   Цитата(Rostislav @ Dec 5 2012, 10:55) Где...   Dec 5 2012, 06:59
- - Rostislav   Кстати, детская арифметика заканчивается начиная с...   Dec 5 2012, 07:11
- - skyv   Я использовал просто таблицу, которую предваритель...   Dec 5 2012, 10:59
|- - Rostislav   Цитата(skyv @ Dec 5 2012, 13:59) Я исполь...   Dec 5 2012, 11:04
|- - Lmx2315   QUOTE (Rostislav @ Dec 5 2012, 15:04) А В...   Dec 5 2012, 11:14
|- - skyv   Цитата(Lmx2315 @ Dec 5 2012, 15:14) ..мог...   Dec 6 2012, 10:52
- - MrYuran   Можно скомбинировать. Таблицу для грубого опреде...   Dec 5 2012, 11:28
|- - Rostislav   Цитата(MrYuran @ Dec 5 2012, 14:28) Можно...   Dec 5 2012, 11:39
- - sysel   Не знаю, как называется метод, но пашет: Код// Выч...   Dec 5 2012, 13:56
- - анатолий   Вот функция корня по алгоритму CORDIC Кодfunction ...   Dec 8 2012, 21:23
|- - Rostislav   Цитата(анатолий @ Dec 9 2012, 00:23) Вот ...   Dec 11 2012, 06:07
|- - анатолий   Цитата(Rostislav @ Dec 11 2012, 08:07) чт...   Dec 11 2012, 19:16
- - TSerg   Кодfunction intSqrt_(Val : Longword) ...   Dec 11 2012, 11:41
|- - akorud   Есть возможность использовать floating-point? Може...   Dec 11 2012, 18:41
- - VitekSVM   http://algolist.manual.ru/maths/count_fast/index.p...   Dec 20 2012, 13:41
- - blackfin   Сто раз уже обсуждали: ReAl.   Dec 21 2012, 06:19
|- - Rostislav   Цитата(blackfin @ Dec 21 2012, 09:19) Сто...   Dec 21 2012, 06:24
|- - beaRTS   Цитата(blackfin @ Dec 21 2012, 09:19) Сто...   Dec 21 2012, 06:27
|- - Rostislav   Цитата(beaRTS @ Dec 21 2012, 09:27) ...я ...   Dec 21 2012, 06:31
- - TSerg   Топик-стартер слушает только себя в попытке изобре...   Dec 21 2012, 07:12
|- - Rostislav   Цитата(TSerg @ Dec 21 2012, 10:12) Топик-...   Dec 21 2012, 11:10
|- - beaRTS   Цитата(Rostislav @ Dec 21 2012, 14:10) ЗЫ...   Dec 22 2012, 08:50
|- - beaRTS   Цитата(Rostislav @ Dec 21 2012, 14:10) ЗЫ...   Dec 22 2012, 09:01
|- - TSerg   Цитата(Rostislav @ Dec 21 2012, 15:10) Ва...   Dec 22 2012, 17:47
- - Rostislav   TSerg, Ваш вариант описывается тут: http://en.wiki...   Dec 22 2012, 08:25
- - beaRTS   по поводу своей идеи начал новую тему. вот здесь к...   Dec 22 2012, 16:06


Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 20th June 2025 - 00:28
Рейтинг@Mail.ru


Страница сгенерированна за 0.01465 секунд с 7
ELECTRONIX ©2004-2016