Что означают две левые угловые скобки "<<" в C #? - PullRequest
43 голосов
/ 22 марта 2010

В основном вопросы в названии. Я смотрю на исходный код MVC 2:

[Flags]
public enum HttpVerbs {
    Get = 1 << 0,
    Post = 1 << 1,
    Put = 1 << 2,
    Delete = 1 << 3,
    Head = 1 << 4
}

и мне просто интересно, что делает двойная левая угловая скоба <<.

Ответы [ 14 ]

7 голосов
/ 30 января 2014

Это подразумевается в ряде ответов, но никогда не указывается напрямую ...

Для каждой позиции, на которую вы сдвигаете двоичное число влево, вы удваиваете исходное значение числа.

Например,

Десятичная дробь 5, сдвинутая влево на единицу, является десятичной 10, или десятичная 5, удвоенная.

Десятичная дробь 5, сдвинутая влево на 3, является десятичной 40 или десятичной 5, удвоенной 3 раза.

7 голосов
/ 29 января 2014

Выражение (1 << N) использует битовое смещение в c #.

В этом случае оно используется для выполнения быстрой целочисленной оценки 2 ^ N, где n равно от 0 до 30.

Хороший инструмент для молодых разработчиков whippersnappers , которые не понимают, как работают сдвиги битов, - это Windows Calc в режиме программиста, который визуализирует влияние сдвигов на числа со знаком разного размера.Функции Lsh и Rsh равны << и >> соответственно.

Оценка с использованием Math.Pow внутри условия цикла (в моей системе) примерно в 7 раз медленнее, чем код вопроса дляN = 10, зависит ли это от контекста.

Кэширование «счетчика циклов» в отдельной переменной немного ускорило бы его, поскольку выражение, включающее длину списка, не нужно пересматривать в каждомитерации.

6 голосов
/ 29 января 2014

Предыдущие ответы объяснили что это делает , но, похоже, никто не догадывался о почему . Мне кажется весьма вероятным, что причина этого кода в том, что цикл повторяется для каждой возможной комбинации элементов списка - это единственная причина, по которой я могу понять, почему вы хотите выполнить итерацию до 2 ^ {list. граф}. Поэтому переменная i будет иметь неправильное имя: вместо индекса (который я обычно интерпретирую как «i»), ее биты представляют собой комбинацию элементов из списка, поэтому (например) первый элемент может быть выбирается, если установлен нулевой бит i ((i & (1 << 0)) != 0), второй элемент, если установлен первый бит ((i & (1 << 1)) != 0) и т. д. Следовательно, 1 << list.Count является первым целым числом, которое не соответствует допустимой комбинации элементов из списка, поскольку оно будет указывать на выбор несуществующего list[list.Count].

5 голосов
/ 22 марта 2010

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

[Fact] public void Bit_shift_left()
{
    Assert.Equal(Convert.ToInt32("0001", 2), 1 << 0); // 1
    Assert.Equal(Convert.ToInt32("0010", 2), 1 << 1); // 2
    Assert.Equal(Convert.ToInt32("0100", 2), 1 << 2); // 4
    Assert.Equal(Convert.ToInt32("1000", 2), 1 << 3); // 8
}
...