IPB
ЛогинПароль:

> Прочтите прежде чем задавать вопрос!

1. Заголовок темы должен быть информативным. В противном случае тема удаляется ...
2. Все тексты программ должны помещаться в теги [code=pas] ... [/code].
3. Прежде чем задавать вопрос, см. "FAQ", если там не нашли ответа, воспользуйтесь ПОИСКОМ, возможно такую задачу уже решали!
4. Не предлагайте свои решения на других языках, кроме Паскаля (исключение - только с согласия модератора).
5. НЕ используйте форум для личного общения, все что не относится к обсуждению темы - на PM!
6. Одна тема - один вопрос (задача)
7. Проверяйте программы перед тем, как разместить их на форуме!!!
8. Спрашивайте и отвечайте четко и по существу!!!

 
 Ответить  Открыть новую тему 
> Квадратный корень двоичного числа и число в степени 2
DarkWishmaster
сообщение 27.05.2011 16:56
Сообщение #1


Бывалый
***

Группа: Пользователи
Сообщений: 168
Пол: Мужской

Репутация: -  3  +


Привет.
Вообщем такая задача:
Дано число X в двоичной системе из N цифр (0,1) , найти число Y=sqrt(x);
для первой задачи:
1<=N<=250 так что тут варинаты типа перевести в 10 и обратно не принимаются.
Вот я решил для противоположной задачи:
Y=x^2 где 1<=N<=120. Только достаточно медлено идет ( из за процедуры Optimze), решил число в векторе поставить и уже умножить два вектора:
Спойлер (Показать/Скрыть)

Квадратный корень думаю можно получить путем перебора всех двоичных чисел из (N div 2)+1 бинарных цифр потом вывести в степень и сравнивать, но если исп. мою програму для степени то время выполнения значительно превысит разрешимое.

Сообщение отредактировано: DarkWishmaster - 27.05.2011 16:58
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
-TarasBer-
сообщение 27.05.2011 19:14
Сообщение #2


Гость






Вот есть известнй алгоритм. Умножений нету. Только вычитания, ну и побитовые операции.
Переписать его нетрудно. Понять намного сложнее. Я вот смог весьма смутно.

Сишный синтаксис знаешь? Если что не ясно - переспроси.

int isqrt4(unsigned x) {
// unsigned - это аналог cardinal, но это неважно
unsigned m, y, b;// объявляем внутренние переменные

m = 0x40000000; // тут любая чётная степень двойки, но заведомо превосходящая икс
y = 0;
while(m != 0) { // Do 16 times.
b = y | m; // битовое or
y = y >> 1; // битовый сдвиг вправо
if (x >= b) { x = x - b; y = y | m; }
m = m >> 2;
}
return y;
}


 К началу страницы 
+ Ответить 
DarkWishmaster
сообщение 27.05.2011 19:16
Сообщение #3


Бывалый
***

Группа: Пользователи
Сообщений: 168
Пол: Мужской

Репутация: -  3  +


Цитата(-TarasBer- @ 27.05.2011 19:14) *

Вот есть известнй алгоритм. Умножений нету. Только вычитания, ну и побитовые операции.
Переписать его нетрудно. Понять намного сложнее. Я вот смог весьма смутно.

Сишный синтаксис знаешь? Если что не ясно - переспроси.

int isqrt4(unsigned x) {
// unsigned - это аналог cardinal, но это неважно
unsigned m, y, b;// объявляем внутренние переменные

m = 0x40000000; // тут любая чётная степень двойки, но заведомо превосходящая икс
y = 0;
while(m != 0) { // Do 16 times.
b = y | m; // битовое or
y = y >> 1; // битовый сдвиг вправо
if (x >= b) { x = x - b; y = y | m; }
m = m >> 2;
}
return y;
}



Си пока не знаю, если не трудно перепеши пожалуйста для Паскаля, постараюсь понять. Я пока пойду почитаю про битовые сдвиги.
Как я понимаю этот алгоритм предназначен для чисел в 10 системе? потому что число длиной в 250 цифр не впишется в стандартные типа, только если симулировать операции сдвига на векторе.

Сообщение отредактировано: DarkWishmaster - 27.05.2011 19:25
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
-TarasBer-
сообщение 27.05.2011 20:38
Сообщение #4


Гость






Дословно переписываю (только заменил знаковый на беззнаковый).

function isqrt4(x: longint): longint;
var m,y,b: longint;
begin
m := $40000000;
y := 0;
while m <> 0 do begin
b := y or m;
y := y shr 1;
if x >= b then begin x := x - b; y := y or m; end;
m := m shr 2;
end;
isqrt4 := y;
end;



> Как я понимаю этот алгоритм предназначен для чисел в 10 системе?

Судя по обилию битовых операций, нетрудно догадаться, что этот алгоритм подогнан именно под представление в двоичной системе.
 К началу страницы 
+ Ответить 
DarkWishmaster
сообщение 27.05.2011 21:20
Сообщение #5


Бывалый
***

Группа: Пользователи
Сообщений: 168
Пол: Мужской

Репутация: -  3  +


Цитата(-TarasBer- @ 27.05.2011 20:38) *

Дословно переписываю (только заменил знаковый на беззнаковый).

function isqrt4(x: longint): longint;
var m,y,b: longint;
begin
m := $40000000;
y := 0;
while m <> 0 do begin
b := y or m;
y := y shr 1;
if x >= b then begin x := x - b; y := y or m; end;
m := m shr 2;
end;
isqrt4 := y;
end;



> Как я понимаю этот алгоритм предназначен для чисел в 10 системе?

Судя по обилию битовых операций, нетрудно догадаться, что этот алгоритм подогнан именно под представление в двоичной системе.

Спасибо. Пойду разбираться, надеюсь пойму хоть каплю в этих операциях.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
-TarasBer-
сообщение 27.05.2011 21:36
Сообщение #6


Гость






Кстати, на будущее.
Процедура убирания двоек из числа (Optimize) пишется не так.


p := 0; // перенос
for k := 255 downto 1 do begin // идём от младших разрядов к старшим
a[k] := a[k] + p; // учитываем перенос, оставшийся с предыдущих разрядов
p := a[k] div 2; // если число получилось больше 1, то запоминаем новый перенос
a[k] := a[k] mod 2; // остаток сохраняем
end;


И в процедуре умножения не надо делать убирание двоек после КАЖДОЙ итерации.
 К началу страницы 
+ Ответить 
DarkWishmaster
сообщение 27.05.2011 21:49
Сообщение #7


Бывалый
***

Группа: Пользователи
Сообщений: 168
Пол: Мужской

Репутация: -  3  +


Цитата(-TarasBer- @ 27.05.2011 21:36) *

Кстати, на будущее.
Процедура убирания двоек из числа (Optimize) пишется не так.


p := 0; // перенос
for k := 255 downto 1 do begin // идём от младших разрядов к старшим
a[k] := a[k] + p; // учитываем перенос, оставшийся с предыдущих разрядов
p := a[k] div 2; // если число получилось больше 1, то запоминаем новый перенос
a[k] := a[k] mod 2; // остаток сохраняем
end;


И в процедуре умножения не надо делать убирание двоек после КАЖДОЙ итерации.

О! Спасибо огромное!
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 

 Ответить  Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 



- Текстовая версия 20.07.2025 1:49
Хостинг предоставлен компанией "Веб Сервис Центр" при поддержке компании "ДокЛаб"