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

> Внимание!

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

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

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


Человек
*****

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

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


Добрый день!
Собственно есть такая головоломка задачка:
Цитата
Напишите функцию setbits(x, p, n, y), возвращающую значение x, в котором n битов, начиная с p-й позиции, заменены на n правых разрядов из y (остальные биты не изменяются).
я ее та решил, но при проверки, она не всегда себя ведет "правильно"(
Мой алгоритм: обнуляем биты в x, которые будем менять. Сдвигаем правые биты y на позиции в которые их необходимо вставить. Производим побитовое или.
Мое решение:
unsigned setbits(unsigned x, int p, int n, unsigned y){
return (x & ( ~( ((~0)<<n)^((~0)<<(p+n)) ) )) |
(y&((~((~0) << n)) << p));
}

решение некоего Richard Heathfield-а, алагоритм мне не ясен..
 unsigned setbits(unsigned x, int p, int n, unsigned y)
{
return (x & ((~0 << (p + 1)) | (~(~0 << (p + 1 - n))))) | ((y & ~(~0 << n)) << (p + 1 - n));
}

программа для тестирования, того же Ричарда..
int main(void)
{
unsigned i;
unsigned j;
unsigned k;
int p;
int n;

for(i = 0; i < 30000; i += 511)
{
for(j = 0; j < 1000; j += 37)
{
for(p = 0; p < 16; p++)
{
for(n = 1; n <= p + 1; n++)
{
k = setbits(i, p, n, j);
printf("setbits(%u, %d, %d, %u) = %u\n", i, p, n, j, k);
}
}
}
}
return 0;
}

Упражнение из K&R #2.6. Мой компилятор: gcc (GCC) 4.2.3 (Ubuntu 4.2.3-2ubuntu7)
Где у меня ошибка?
Заранее благодарен.

Сообщение отредактировано: compiler -


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


Гость






Цитата
Где у меня ошибка?
Ну, посмотри, что ты делаешь с Y...

Ты должен сначала получить маску для последних N бит числа Y: ~((~0 << n))
потом число Y умножить на эту маску (чтоб получить именно последние N бит): (y & ~((~0 << n)))
и только потом сдвинуть на p бит: ((y & ~((~0 << n))) << p)

А ты что делаешь? (обрати внимание на скобки)
Сначала находишь маску для N бит, тут все верно... Потом зачем-то ее сдвигаешь на P бит влево, и только потом умножаешь Y на полученное значение. А значит, ты берешь не правые разряды Y, как требуется в задании, а те, что находятся в том же месте, где и замещаемые в X...

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


Человек
*****

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

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


спасибо, буду смотреть...


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


Человек
*****

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

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


Что-то у меня не получается... Теперь я запутался в задании(
Берем входные данные (0, 1, 2, 37). Что мы должны получить на выходе? Единицу или двойку? По-моему, двойку..
y == 37==100101b
x == 0 ==00000b
После замены получаем: 00010b == 2, а Ричард говорит что 1... Или он нумерует биты с единицы? Или подразумевается, что биты заменяются вправо?

Сообщение отредактировано: compiler -


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


Гость






Цитата
Или подразумевается, что биты заменяются вправо?
Да, именно это у Ричарда и делается... Биты нумеруются с 0, но вот заменяются не N бит слева начиная от P-го, а N бит справа, включая бит №P...
 К началу страницы 
+ Ответить 
сообщение
Сообщение #6


Человек
*****

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

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


Цитата
Да, именно это у Ричарда и делается...

а откуда такая двуякая трактовка задания в столь популярной книге?) причем в оригиналие тоже
Цитата
Exercise 2-6. Write a function setbits(x,p,n,y) that returns x with the n bits that begin at position p set to the rightmost n bits of y, leaving the other bits unchanged.


volvo, спасибо, теперь хоть буду знать что этот Ричард делает..

Сообщение отредактировано: compiler -


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

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

 





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