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

> Внимание!

1. Пользуйтесь тегами кода. - [code] ... [/code]
2. Точно указывайте язык, название и версию компилятора (интерпретатора).
3. Название темы должно быть информативным.
В описании темы указываем язык!!!

Наладить общение поможет, если вы подпишитесь по почте на новые темы в этом форуме.

 
 Ответить  Открыть новую тему 
> написать макрос, Си
сообщение
Сообщение #1


Бывалый
***

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

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


Написать макрос, реализующих циклические перестановки (влево-вправо) на k бит, первых n бит, 32-хбитовоц структуры (unsigned).Обьясните ктонибудь что за циклические перестановки ?Ато я никак не могу врубиться smile.gif
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #2


Гость






Цитата
Обьясните ктонибудь что за циклические перестановки ?
При обычном сдвиге, скажем, влево, у тебя все биты, выходящие слева за разрядную сетку теряются, справа добавляются нули:
01010011
сдвиг влево на 2
01001100
Как видишь, 01 потерялось...

Твоя задача - написать макрос, который сдвинет заданное число циклически, то есть, бит, выходящий слева, добавляется справа (и наоборот, если сдвигаем вправо, то "убегающий бит" должен добавиться слева). Для предыдущего примера:

01010011
циклический сдвиг влево на 2
01001101

Так понятнее?
 К началу страницы 
+ Ответить 
сообщение
Сообщение #3


Бывалый
***

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

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


Цитата(volvo @ 21.05.2008 17:13) *

При обычном сдвиге, скажем, влево, у тебя все биты, выходящие слева за разрядную сетку теряются, справа добавляются нули:
01010011
сдвиг влево на 2
01001100
Как видишь, 01 потерялось...

Твоя задача - написать макрос, который сдвинет заданное число циклически, то есть, бит, выходящий слева, добавляется справа (и наоборот, если сдвигаем вправо, то "убегающий бит" должен добавиться слева). Для предыдущего примера:

01010011
циклический сдвиг влево на 2
01001101

Так понятнее?

Да спасибо теперь понял!
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #4


Бывалый
***

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

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


#define SDVIG(s,n,c) (c=='L'? s=(s<<n)|(s>>32-n):c=='R'? s=(s>>n)|(s<<32-n):printf("ERROR:'%c'",c)) 
Правильно я реализовал требуемый макрос?
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #5


Гость






Стой, стой... Не так... Я сразу не очень внимательно прочел задание...

Тебе надо не просто циклически сдвинуть число на сколько-то бит, тебе надо сдвинуть N первых бит числа циклически на K бит. То есть, если возьмем N = 5, K = 3 и 32-битное число s:
00110101 00001010 00000000 000000002 = (13578 * 65536)10
(для простоты я рассматриваю только первые 16 бит, остальные пусть будут нулевыми, это как раз и даст умножение на 216 = 65536), то "зацикливать" надо только первые 5 бит, остальные должны остаться на своих местах, т.е., результат будет:
XXXXX101 00001010 00000000 000000002, где выделенный фрагмент - это N (5 этом случае) бит 00110, сдвинутые циклически на K (т.е, на 3) :
было 00110
стало 10001
Итого получаем:
10001101 00001010 00000000 000000002 = (36106 * 65536)10...

Теперь другое. Не стОит сразу бросаться и писать макросы. Их очень сложно отлаживать, поэтому сначала пишется программка, в которой это все делается без макросов, обычным способом:
#include <stdio.h>
int main() {
unsigned int T;
char c = 'L';
unsigned s = 13578 * 65536;
int n = 5, k = 3;

if(c == 'L') {
T = s & ((0xffffffff >> (32 - n)) << (32 - n));
T = (T << k) | (T >> (n - k));
s = T | (s & (0xffffffff >> n));
}
printf("%u", s / 65536);
return 0;
}

Как видишь, получилось именно 36106, значит, фрагмент работает правильно. Сделай аналогичные преобразования для сдвига вправо, чтоб оно работало правильно, а потом уже преобразуй в макрос...
 К началу страницы 
+ Ответить 
сообщение
Сообщение #6


Бывалый
***

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

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


Цитата(volvo @ 21.05.2008 20:02) *

Стой, стой... Не так... Я сразу не очень внимательно прочел задание...

Тебе надо не просто циклически сдвинуть число на сколько-то бит, тебе надо сдвинуть N первых бит числа циклически на K бит. То есть, если возьмем N = 5, K = 3 и 32-битное число s:
00110101 00001010 00000000 000000002 = (13578 * 65536)10
(для простоты я рассматриваю только первые 16 бит, остальные пусть будут нулевыми, это как раз и даст умножение на 216 = 65536), то "зацикливать" надо только первые 5 бит, остальные должны остаться на своих местах, т.е., результат будет:
XXXXX101 00001010 00000000 000000002, где выделенный фрагмент - это N (5 этом случае) бит 00110, сдвинутые циклически на K (т.е, на 3) :
было 00110
стало 10001
Итого получаем:
10001101 00001010 00000000 000000002 = (36106 * 65536)10...

Теперь другое. Не стОит сразу бросаться и писать макросы. Их очень сложно отлаживать, поэтому сначала пишется программка, в которой это все делается без макросов, обычным способом:
#include <stdio.h>
int main() {
unsigned int T;
char c = 'L';
unsigned s = 13578 * 65536;
int n = 5, k = 3;

if(c == 'L') {
T = s & ((0xffffffff >> (32 - n)) << (32 - n));
T = (T << k) | (T >> (n - k));
s = T | (s & (0xffffffff >> n));
}
printf("%u", s / 65536);
return 0;
}

Как видишь, получилось именно 36106, значит, фрагмент работает правильно. Сделай аналогичные преобразования для сдвига вправо, чтоб оно работало правильно, а потом уже преобразуй в макрос...

ну вобщем с программой все ясно, а вот как в макрос засунуть временную переменную Т ?
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #7


Бывалый
***

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

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


Все написал макрос работает правильно!!!Спасибо!
#define L(s,n,k) s=((((s & ((0xffffffff >> (32 - n)) << (32 - n)))<<k)|((s & ((0xffffffff >> (32 - n)) << (32 - n)))>>(n-k)))| (s & (0xffffffff >> n)))
#define R(s,n,k) s=((((s & ((0xffffffff << (32 - n)) >> (32 - n)))>>k)|((s & ((0xffffffff << (32 - n)) >> (32 - n)))<<(n-k)))| (s & (0xffffffff << n)))
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #8


Гость






Цитата
работает правильно!
L - да, R - нет... Для того, чтобы циклически сдвинуть вправо кусок битовой последовательности совершенно недостаточно просто поменять все << на >> и наоборот... Проверяем:

...
int main() {
unsigned s = 13578 * 65536;
int n = 7, k = 4;

R(s, n, k);
printf("%u", s / 65536);
return 0;
}

Чему должен быть равен результат?

00110101000010102
сдвигаем выделенную область на 4 бита вправо:
10100011000010102 = 4173810

А теперь запусти программу...
 К началу страницы 
+ Ответить 

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

 





- Текстовая версия 17.01.2021 2:13
500Gb HDD, 6Gb RAM, 2 Cores, 7 EUR в месяц — такие хостинги правда бывают
Связь с администрацией: bu_gen в домене octagram.name