Модераторы: bsa
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Туториалы по битовым операциям, Есть ли где-нибудь такие? 
:(
    Опции темы
Boguslav
Дата 2.10.2012, 22:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 4
Регистрация: 21.12.2011

Репутация: нет
Всего: нет



Я недавно начал учить си по книге K&R. Так все круто, только никак не понимаю функций с битовыми операциями, вроде такой:
Код

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));
}
Взял отсюда: http://users.powernet.co.uk/eton/kandr2/krx206.html

Подскажите, может есть в интернете какие-нибудь туториалы попроще с примерами и подробным описанием битовых операций
PM MAIL   Вверх
bsa
Дата 2.10.2012, 23:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 85
Всего: 196



Boguslav, ты сам виноват. Не надо было брать такую сложную и, главное, совершенно непонятную функцию (программист, который ее писал, не думал о том, что кто-то будет читать его код), хорошо, что еще скобки расставлены и не надо по таблицам приоритеты уточнять. Чтобы ее понять надо разложить на простейшие операции:
x & y - побитовое "И": 1010 & 0110 = 0010
~x - инверсия всех битов x: ~1010 = 0101
x | y - побитовое "ИЛИ": 1010 | 0110 = 1110
x << y - сдвиг всех битов на y влево (аналог умножения x на 2 в степени y): 00001010 << 2 = 00101000
PM   Вверх
borisbn
Дата 3.10.2012, 08:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 21
Всего: 135



Цитата(Boguslav @  2.10.2012,  22:14 Найти цитируемый пост)
~0 << n

буквально сегодня прочитал у Карпова, что это - UB, т.к. ~0 - знаковое (значение == -1), а сдвигать знаковые нельзя.
Так что пример не только "сложный и, главное, совершенно непонятный", но ещё и некорректный


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
math64
Дата 3.10.2012, 10:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 12
Всего: 72



Можно сдвигать знаковые! В процессоре даже есть отдельные команды для знакового и беззнакового сдвига.
PM   Вверх
borisbn
Дата 3.10.2012, 10:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 21
Всего: 135



Для выражения E1 << E2:
Цитата
if E1 has a signed type and non-negative value, and E1*2^E2 is representable in the result type, then that is the resulting value; otherwise, the behavior is undefined

т.е. знаковые-таки можно, но знаковые и при этом отрицательные - нельзя. а ~0 - знаковое и отрицательное


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
Dem_max
Дата 3.10.2012, 11:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1780
Регистрация: 12.4.2007

Репутация: 4
Всего: 39



Можно и знаковые и без знаковые операции совершать и чтобы компилятор понимал в каком случае где и как работать нужно конкретно указывать
char
unsigned char



--------------------
Американские программисты долго не могли понять, почему русские при зависании Windоws всё время повторяют "Твой зайка написал" ("Yоur bunnу wrоte")
PM MAIL   Вверх
bsa
Дата 3.10.2012, 11:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 85
Всего: 196



math64, это процессор x86 и z80 может сдвигать знаковые, а вот ARM может? По стандарту: сдвиг отрицательного числа - это UB.
PM   Вверх
Alexeis
Дата 3.10.2012, 11:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 4
Всего: 459



Цитата(bsa @  3.10.2012,  12:19 Найти цитируемый пост)
По стандарту: сдвиг отрицательного числа - это UB. 

  Можно ссылку на стандарт? Такая операция уже сто лет как успешно работает в наших приборах на процах PXA25x (ARM/THUMB). Используется как замена целочисленного деления на числа кратные 2м. Массивы содержат как положительные так и отрицательные значения. Результат всегда корректный. Единственное, что получается, так это ошибка на единицу по сравнению с целочисленным делением, но это так на х86 тоже. Она возникает только на отрицательных числах в дополнительном коде.


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
xvr
Дата 3.10.2012, 11:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 35
Всего: 223



Цитата(Alexeis @  3.10.2012,  11:48 Найти цитируемый пост)
Такая операция уже сто лет как успешно работает в наших приборах на процах PXA25x (ARM/THUMB). Используется как замена целочисленного деления на числа кратные 2м.

Не такая. Речь идет о сдвиге влево, это замена целочисленного умножения 'на числа кратные 2м'

Цитата(Alexeis @  3.10.2012,  11:48 Найти цитируемый пост)
Можно ссылку на стандарт?

С99, раздел 6.5.7 Bitwise shift operators, пункт 4
Цитата

The result of E1 << E2 is E1 left-shifted E2 bit positions; vacated bits are filled with
zeros. If E1 has an unsigned type, the value of the result is E1 × 2**E2, reduced modulo
one more than the maximum value representable in the result type. If E1 has a signed
type and nonnegative value
, and E1 × 2**E2 is representable in the result type, then that is
the resulting value; otherwise, the behavior is undefined.


С++11, раздел 5.8 Shift operators, пункт 2:
Цитата

The value of E1 << E2 is E1 left-shifted E2 bit positions; vacated bits are zero-filled. If E1 has an unsigned
type, the value of the result is E1 × 2**E2, reduced modulo one more than the maximum value representable
in the result type. Otherwise, if E1 has a signed type and non-negative value, and E1×2**E2 is representable
in the result type, then that is the resulting value; otherwise, the behavior is undefined.


Добавлено через 2 минуты и 58 секунд
Цитата(Dem_max @ 3.10.2012,  11:17)
Можно и знаковые и без знаковые операции совершать и чтобы компилятор понимал в каком случае где и как работать нужно конкретно указывать
char
unsigned char

Где вы там вообще какой бы то ни было char увидели?


Это сообщение отредактировал(а) xvr - 3.10.2012, 12:00
PM MAIL   Вверх
volatile
Дата 3.10.2012, 20:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

Репутация: 16
Всего: 85



Цитата(xvr @  3.10.2012,  11:58 Найти цитируемый пост)
Не такая. Речь идет о сдвиге влево,

xvr, ну там же, следующим пунктом и о сдвиге вправо:

Цитата(ISO/IEC 14882:2011)
5.8.3 The value of E1 >> E2 is E1 right-shifted E2 bit positions. If E1 has an unsigned type or if E1 has a signed type and a non-negative value, the value of the result is the integral part of the quotient of E1/2**E2. If E1 has a signed type and a negative value, the resulting value is implementation-defined.

В общем разница между сдвигом влево и сдвигом вправо, это выбор между "behavior is undefined" и "implementation-defined"
С++ стандарт как всегда, э....   "Чёток и Конкретен!"  smile

PM MAIL   Вверх
borisbn
Дата 3.10.2012, 20:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 21
Всего: 135



> С++ стандарт как всегда
> это выбор между "behavior is undefined" и "implementation-defined"
 smile 
Сделал точно такой же вывод, когда читал этот раздел

> Такая операция уже сто лет как успешно работает
Ну Вы ж должны понимать, что UB и "успешно работает там-то и там-то" - не антонимы


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
Alexeis
Дата 3.10.2012, 20:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 4
Всего: 459



Цитата(borisbn @  3.10.2012,  21:22 Найти цитируемый пост)
> Такая операция уже сто лет как успешно работает
Ну Вы ж должны понимать, что UB и "успешно работает там-то и там-то" - не антонимы 

  Ну bsa писал так как-будто АРМ не умеет такие операции делать. Т.е. вполне определенный проц. На счет сдвига вправо я уже не помню использовался или нет для отрицательных чисел, но думаю что использовался успешно, поскольку в отсутствии сопроцессора часто приходиться числа сдвигать, чтобы избежать потери точности в различных операциях.


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
Dem_max
Дата 4.10.2012, 04:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1780
Регистрация: 12.4.2007

Репутация: 4
Всего: 39



Цитата

Где вы там вообще какой бы то ни было char увидели?

Ну давай тогда другие типы подставь.


--------------------
Американские программисты долго не могли понять, почему русские при зависании Windоws всё время повторяют "Твой зайка написал" ("Yоur bunnу wrоte")
PM MAIL   Вверх
baldina
Дата 4.10.2012, 09:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 15
Всего: 101



Цитата(bsa @  3.10.2012,  11:19 Найти цитируемый пост)
 процессор x86 и z80 может сдвигать знаковые, а вот ARM может? 

вы знаете хоть какой-нибудь процессор, понимающий тип операндов? упомянутые не понимают, все они работают с битовым представлением, выполняя конкретную команду. лично мне неизвестны процессоры, работающие иначе. если знаете, поделитесь.

другое дело, в какие инструкции компилятор превращает x<<y
хотя именно в ARM для сдвига влево предусмотрена лишь одна операция LSL (и четыре для сдвига вправо)

Цитата(borisbn @  3.10.2012,  08:56 Найти цитируемый пост)
прочитал у Карпова

а это кто?

PM MAIL   Вверх
bsa
Дата 4.10.2012, 09:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 85
Всего: 196



Цитата(baldina @  4.10.2012,  10:48 Найти цитируемый пост)
а это кто?

Это тот, кто pvs-studio рекламирует тут.
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0653 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.