Dmi*_*try 1 bit-manipulation operators bit swift
Swift 中 &<< 和 << 运算符有什么区别?似乎它们返回相同的结果:
print(2 << 3) // 16
print(2 &<< 3) // 16
Run Code Online (Sandbox Code Playgroud)
该FixedWithInteger协议将“屏蔽左移运算符”定义&<<为
返回将值的二进制表示向左移位指定位数的结果,将移位量屏蔽为类型的位宽。
&<<当您需要执行移位并确保移位量在范围内时,请使用屏蔽左移运算符 ( )0..<lhs.bitWidth。在移位之前,屏蔽左移位运算符将移位屏蔽到此范围。使用此屏蔽值执行移位。
因此,如果移位量大于或等于左操作数的位宽,结果可能会有所不同: 示例:
print(2 << 70) // 0
print(2 &<< 70) // 128
Run Code Online (Sandbox Code Playgroud)
这里的移位量 (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
Run Code Online (Sandbox Code Playgroud)
这里的第一个结果是-1因为将有符号整数右移会用符号位填充左侧的空位置。第二个结果是-128因为移位量为零:8 % 8 = 0。
SR-6749 中还描述了命名和预期用途:
然而,操作符的目标是永远不会发生这种包装行为——当你知道你的移位量是 <= 位宽的静态知识时,你会使用它。通过屏蔽,您和编译器可以同意不需要分支,因此您可以在没有零分支和零风险的未定义行为(负或太大的转变)的情况下获得稍快的代码。
文档令人困惑,因为它们给出了一个我认为没有人会故意编写的示例——依靠包装行为来使用一些超出范围的值作为移位量。
因此,使用屏蔽移位运算符可以提高性能。许多示例可以在 Swift 标准库的源代码中找到,例如在UTF8.swift 中。
| 归档时间: |
|
| 查看次数: |
101 次 |
| 最近记录: |