суббота, января 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 комментария:

  1. Анонимный29/1/06 08:02

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

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

    ОтветитьУдалить
  2. Анонимный29/1/06 15:36

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

    ОтветитьУдалить
  3. Анонимный29/1/06 20:00

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

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

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

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

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

    ОтветитьУдалить