Протокол FixedWithInteger
определяет «оператор маскирования влево» &<<
как
Возвращает результат смещения двоичного представления значения на
указанное число цифр слева, маскируя величину сдвига до
битовая ширина типа.
Используйте оператор маскирования влево (&<<
), когда вам нужно выполнить
сдвиг и уверены, что величина сдвига находится в диапазоне
0..<lhs.bitWidth
. Перед сдвигом маскирующий левый оператор сдвига
маскирует сдвиг в этом диапазоне. Сдвиг выполняется с использованием этого
замаскированное значение.
Таким образом, результаты могут отличаться, если величина сдвига больше или равна битовой ширине левого операнда: Пример:
print(2 << 70) // 0
print(2 &<< 70) // 128
Здесь величина сдвига (70) больше, чем бит с Int
(64), так что 2 << 70
оценивается как ноль.
Во второй строке число сдвигается влево на 70%, 64 = 6 бит.
Существует также аналогичный «оператор маскирования вправо» &>>
. Пример:
let x = Int8.min // -128 = 0b10000000
print(Int8.min >> 8) // -1 = 0b11111111
print(Int8.min &>> 8) // -128 = 0b10000000
Здесь первый результат равен -1
, поскольку смещение целого числа со знаком вправо заполняет пустые позиции слева битом знака . Второй результат равен -128
, поскольку величина сдвига равна нулю: 8 % 8 = 0
.
Наименование и предполагаемое использование также описаны в SR-6749 :
Цель оператора, однако, никогда не заключаться в такой упаковке
поведение происходит - это то, что вы используете, когда у вас есть статические знания
что ваша величина сдвига <= ширина бита. Маскируя, вы и
компилятор может согласиться, что ветка не нужна, так что вы получите немного
более быстрый код без нулевого ветвления и нулевого риска неопределенного поведения
(какой будет отрицательный или слишком большой сдвиг). </p>
Документы сбивают с толку, потому что они приводят пример, который я не думаю,
кто-нибудь когда-либо намеренно писал - полагаясь на поведение обертки
использовать некоторое значение за пределами для суммы смены.
Таким образом, использование маскированных операторов сдвига может повысить производительность. Многие примеры можно найти в исходном коде стандартной библиотеки Swift, например, в UTF8.swift .