Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
Самоучитель PHP 5 / 6 (3 издание). Авторы: Кузнецов М.В., Симдянов И.В. PHP 5. На примерах. Авторы: Кузнецов М.В., Симдянов И.В., Голышев С.В. PHP Puzzles. Авторы: Кузнецов М.В., Симдянов И.В. Самоучитель MySQL 5. Авторы: Кузнецов М.В., Симдянов И.В. MySQL 5. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Разное

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Поразрядные операции
 
 автор: neadekvat   (23.05.2010 в 01:17)   письмо автору
 
 

Решил таки разобраться окончательно в этой теме, но гугл что-то скуп.
Вот то, что я понял (правильно ли?)
Возьмем два числа: 2 и 3 (0010 и 0011 в двоичном представлении соответственно)
При поразрядная конъюнкции (2 & 3) интерпритатор будет соответственно сранивать биты, в итоге получится такая картина
2..0010
3..0011
----------
2..0010
И так как получилось число, отличное от нуля, интерпритатор даст true. По аналогии приходит понимание |, ^, ~

Но вот сдвиги я никак понять не могу.
Нашел пример:
9 - это 00001001
9<<3 получим 01001000
Судя по всему, таки сдвинули влево на три бита, дорисовав нули справа. Но ведь 3 здесь - десятичная не двоичная, как минимум (в какой сс, кстати?). А если подставить двоичные эквиваленты, то непонятна логика мне..
00001001 << 00000011

  Ответить  
 
 автор: cheops   (23.05.2010 в 01:29)   письмо автору
 
   для: neadekvat   (23.05.2010 в 01:17)
 

В сдвиге никакой хитрости нет - это обычный сдвиг разрядов. 3 это 3, в десятичной системе мы записываем это число как 3, в двоичной 11 = 1*2 + 1*1 = 3, но и там и там это обозначает 3 штуки. Просто в сдвигах не нужно тройку переводить в бинарное представление - можно, если вам удобнее (машина так и делает, так как она числа только 0 и 1 представляет), но люди обычно используют десятичное представление. Тут хитрость в том, что числа как были так и остаются, меняется лишь их запись, число 9 (1001) можно записать множеством способов
1001 = 1*8 + 0*4 + 0*2 + 1*1 = 9 = nine = девять
Как вы его не обозначайте это будет 9 предметов, а в бинарный код мы это число переводим только потому, что машине с эти представлением проще. Но и для нас с вами и для машины числа означают одинаковое количество предметов, нулей в данном случае - меняется лишь их представление. Это ведь тоже самое что сложение и вычитание в десятичной системе, только вместо 10 цифр - 2 цифры. А сдвиг, это по сути умножение на 10, 100, 1000 или соответственно деление. По сути в десятичной системе эта операция была бы чем-то вроде
4567<<3 = 4567000
Суть поразрядных операций в том, что вы оперируете разрядами, т.е. положением цифр в записи числа (сами числа при этом своего значения не меняют - 9 остается 9, а 3 - это 3).

  Ответить  
 
 автор: neadekvat   (23.05.2010 в 01:50)   письмо автору
 
   для: cheops   (23.05.2010 в 01:29)
 

Ага, вот теперь понятно стало :) Благодарю!

  Ответить  
 
 автор: Красная_шляпа   (23.05.2010 в 11:57)   письмо автору
 
   для: neadekvat   (23.05.2010 в 01:50)
 

А шо тут понимать?

>>> 1 << 10 # 1 * 2^10
1024
>>> 3 << 10 # 3 * 2^10
3072
>>> 1024 >> 4 # 1024 / 2^4
64

Смысла в этих сдвигах кроме как перевод из байтов в килобайты не вижу

  Ответить  
 
 автор: Trianon   (23.05.2010 в 12:08)   письмо автору
 
   для: Красная_шляпа   (23.05.2010 в 11:57)
 

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

  Ответить  
 
 автор: neadekvat   (23.05.2010 в 12:21)   письмо автору
 
   для: Trianon   (23.05.2010 в 12:08)
 

Но может ли такое понадобиться в web-программировании? То, что умножение и деление на степени числа два быстрее происходит, это я понял.
Но разрядные сетки.. в википедии что-то про IP адрес говорится, может, разве что для работы непосредственно с ним :)

  Ответить  
 
 автор: Trianon   (23.05.2010 в 12:40)   письмо автору
 
   для: neadekvat   (23.05.2010 в 12:21)
 

>Но может ли такое понадобиться в web-программировании?

Может ли повредить бридность сотруднику Макдональдса?

  Ответить  
 
 автор: neadekvat   (23.05.2010 в 12:59)   письмо автору
 
   для: Trianon   (23.05.2010 в 12:40)
 

Сотруднику Макдональдса вряд ли :) Однако я тот вопрос задал не с мыслью "Ну и зачем мне с этим разбираться?", а с мыслью "Вот я разобрался - где я могу это применить". Притом не разрядные операции ради разрядных операций, а, возможно, более быстрое или легкое решение в каких-то ситуациях.

  Ответить  
 
 автор: sim5   (23.05.2010 в 13:05)   письмо автору
 
   для: neadekvat   (23.05.2010 в 12:59)
 

Легкость не обязательно главный критерий. Да и "разрядных", это не обязательно по-разрядно в прямом смысле слова.

  Ответить  
 
 автор: neadekvat   (23.05.2010 в 13:21)   письмо автору
 
   для: sim5   (23.05.2010 в 13:05)
 

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

Но все порязрядные операции, что я в гуле находил (в основном учебники по С/С++) рассказывали именно об этом (т.е. побитовое сравнение)

  Ответить  
 
 автор: sim5   (23.05.2010 в 13:43)   письмо автору
 
   для: neadekvat   (23.05.2010 в 13:21)
 

Вы либо сути не понимаете операций, либо вас сбивает столку то, что эти операции в мануале обозначены как побитовые. Но не интерпритатор в конечном итоге решает задачи, а регистры процессора. И выполнять бутут они не задачу &, а команду прошитую в процессоре. И если вас просто интересует, что получится в итоге при:
7 & 5
то просессор просто соеденит (он собственно при очень многих операциях так поступает), регистр А со значеним 7, с регистром В со значеним 5, как n элементов 2И, и выполнить сразу операцию, поместив ее результат в регистор А. При этом будут установлены и соответствующие флаги в флаговом регистре. Все, забирайте результат.
Побитовость для машины, это лирика, пока вы явно не запросите - а что будет во втором разряде после этой операции.
Лигические операции, это не обязательно бегать по битам слова и выяснять чего там в нем.

PS. Я из-за этого "Но может ли такое понадобиться в web-программировании?", только и заговорил.
Вы постоянно используете логические опрерции: &&, ||, например, сюда же и if, только в этом случае интерпретатор интересует не результат операции как таковой, а значение флагового регистра. То что назвали в мануале "побитовыми операциями" вычисляется также, но тут важен сам результат операции, хотя если поставлено условие, то опять флаг ее.

  Ответить  
 
 автор: neadekvat   (23.05.2010 в 14:01)   письмо автору
 
   для: sim5   (23.05.2010 в 13:43)
 

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

Но, например, (1 & 2) даст ложь, а (1 && 2) даст правду. Значит, использовать побитовые операции в качестве логических надо при каких-то определенных условиях?

  Ответить  
 
 автор: sim5   (23.05.2010 в 14:08)   письмо автору
 
   для: neadekvat   (23.05.2010 в 14:01)
 

В первом случае вас интересует результат (не один разряд из двух операндов не даст 1), во втором случае истинны ли оба операнда (в данном примере не один из них не равен 0). В первом случае вам будет возвращено значение аккумулятора, во втором флагового регистра. Что вас удивляет?
Если вы к первому добавите условие if(1 & 2), то получите значение флогового регистра.
Все нужно использовать по назначению, от потребности задачи.

  Ответить  
 
 автор: neadekvat   (23.05.2010 в 14:21)   письмо автору
 
   для: sim5   (23.05.2010 в 14:08)
 

Вот сейчас как раз и читаю википедию в поисках задач, решаемых битовыми операциями :)

  Ответить  
 
 автор: Саня   (23.05.2010 в 13:58)   письмо автору
 
   для: neadekvat   (23.05.2010 в 12:21)
 

> Но может ли такое понадобиться в web-программировании?
Очень часто встречаются упакованные поля (или набор флагов) в бинарных файлах. Соответственно, в web-программировании, такое может понадобиться если работаете с бинарными файлами напрямую.

IP-адрес — на самом деле число размером 4 байта. Для его представления в "человеческий" вид, можно использовать поразрядные операции. А операции с масками вообще не имеют смысла без побитовых операторов.

Битовые операции часто требуются при реализации криптографических и хеш-аглоритмов.

  Ответить  
 
 автор: neadekvat   (23.05.2010 в 12:20)   письмо автору
 
   для: Красная_шляпа   (23.05.2010 в 11:57)
 

Когда понимаешь какую-то тему, она сразу начинает казаться простой (в большинстве случаев) :)

  Ответить  
 
 автор: Trianon   (23.05.2010 в 01:54)   письмо автору
 
   для: neadekvat   (23.05.2010 в 01:17)
 

>9<<3 получим 01001000
>Судя по всему, таки сдвинули влево на три бита, дорисовав нули справа.
>Но ведь 3 здесь - десятичная не двоичная, как минимум (в какой сс, кстати?).

3 здесь именно что десятичная. Правда на одноразрядном числе этого не видно.
Но если Вы попробуете вычислить 1<<10 , то увидите 1024 (то есть в двоичном представлении единицу с десятью нулями)
Впрочем 1<<010 уже даст единицу с восемью нулями, а 1<<0x10 - с шестнадцатью.
Так что какой вид константы выбираете - такую сс и получаете.

  Ответить  
 
 автор: neadekvat   (23.05.2010 в 14:03)   письмо автору
 
   для: neadekvat   (23.05.2010 в 01:17)
 

Понял, где вчера лохонулся. Гуглил по запросу "поразрядные операции", сейчас попробовал по "битовые операции" - уже другое дело :)

  Ответить  
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования