В чем разница между операторами & << и << в Swift? - PullRequest
1 голос
/ 11 мая 2019

В чем разница между операторами & << и << в Swift?Кажется, они возвращают одинаковые результаты: </p>

print(2 << 3) // 16
print(2 &<< 3) // 16

1 Ответ

4 голосов
/ 11 мая 2019

Протокол 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 .

...