суббота, января 28, 2006

Когда x/2 не равно x>>1

Наткнулась на блоге The Old New Thing на размышления на тему When is x/2 different from x>>1?. Там автор ссылается на Стандарт C, а не C++, но в целом все похоже. Итак, известно соотношение между сдвигами и делением и умножением на 2 в С++.
x*2 эквивалентно x<<1
x/2 эквивалентно x>>1

Соотношения эти выполняются не всегда. При сдвиге влево, x<<1, результат еще берется по модулю ULONG_MAX+1 или UINT_MAX+1 в зависимости от типа x. То есть при достаточно большом x первое соотношение выполнено не будет.
Если x отрицательно, то по Стандарту (5.8) поведение при сдвиге влево вовсе не должно как-то соотноситься с умножением на 2, а при сдвиге вправо зависит от реализации (implementation-defined). Например, при вычислении выражения (-1)>>1 я получила -1 во всех компиляторах, в которых смотрела. Хотя (-1)/2 это 0.
Microsoft Visual C++ Toolkit 2003:
-1
MSVC++6.0:
-1
MinGW gcc 3.4.4:
-1

Сдвиги можно использовать вместо деления и умножения, потому что они быстрее. Но вообще мне думается, что современные компиляторы все это сами неплохо оптимизируют.

4 коммент.:

Анонимный комментирует...

Елена, ну вроде вы как бы очевидные достаточно вещи говорите... Кто ваша целевая аудитория?

Вообще, когда надо умножать на 2, так лучше пользоваться умножением, а не сдвигом. В 99.9% случаях вы ничего не сэкомоните, а только будете напрасно забивать голову тем, что случится в случае переполнения, отрицательного числа, мнимого числа, и так далее.

Анонимный комментирует...

"А нам нравится" (с)
Вещи очевидные достаточно часто забываются. Освежить знания никогда не вредно, верно?

Анонимный комментирует...

А мне (автору первой реплики) еще фотка Алены нравится. Мило так...

Alena комментирует...

Елена, ну вроде вы как бы очевидные достаточно вещи говорите...

Очевидность - это очень индивидуальное понятие...

Кто ваша целевая аудитория?

Люди, интересующиеся программированием вообще, программированием на C++ в частности.