Swift中的按位移位和运算符

一点是最小的信息,可以是1或0(开/关)。 八位加在一起称为一个字节。 Swift中UInt8由8位表示。 此无符号整数与有符号整数Int8在于Int8使用1位表示该整数是正数还是负数。 用八位表示一个数字意味着我们可以用UInt8表示2 = 256个不同的数字。

  0 = 00000000 2 = 00000010 4 = 00000100 8 = 00001000 
1 = 00000001 3 = 00000011 5 = 00000101 9 = 00001001
6 = 00000110 10 = 00001010
7 = 00000111 11 = 00001011
12 = 00001100
13 = 00001101
14 = 00001110
15 = 00001111
...
255 = 11111111

按位移位

这是用一个示例最容易解释的:假设我们用00001000表示数字8,然后左移<< 。 这意味着所有位将通过删除左位向左移动一位,并在右侧插入值为0的新位。 这将最终以00010000表示的第16位。 如果执行右移>> ,则所有位都将向右移动一位,最后以00000100表示数字4。因此,向左移动将数字翻倍,而向右移动将数字减半。

按位运算符

按位NOT运算符~反转数字中的所有位: 00001111将变为11110000 。 它是一个前缀运算符,出现在对其运算的值之前:

 让位:UInt8 = 0b00001111 //等于15 
令vertedBits =〜bits //等于240(11110000)

按位与运算符&组合两个数字的位。 仅当两个输入数字的位均等于1 ,它才返回一个新的数字,其位设置为1
11111100
00111111
— — — —
00111100

 让middleBits = firstBits&lastBits 

按位或运算符| 比较两个数字的位。 如果任一输入数字的位等于1则运算符返回一个新的数字,其位设置为1
10110010
01011110
— — — —
11111110

 让combinedbits = someBits | 更多位 

按位异或运算符(XOR) ^比较两个数字的位。 操作员返回一个新的数字,该数字在输入位不同的地方设置为1 ,在输入位相同的地方设置为000010100
00000101
— — — —
00010001

 让outputBits = firstBits ^ otherBits 

按位运算符的用例

Swift标准库通过使用OptionSet协议使使用位掩码和按位操作变得容易。 在Objective-C中 ,通常将一组布尔选项表示为枚举实例。 假设我们要安排提醒,并且希望将安排存储在单个值中。 在Objective-C中,我们将编写如下内容:

  typedef NS_OPTIONS(NSUIInteger,Schedule){ 
星期一=(1 << 0),// 00000001 = 1
星期二=(1 << 1),// 00000010 = 2
星期三=(1 << 2),// 00000100 = 4
星期四=(1 << 3),// 00001000 = 8
星期五=(1 << 4),// 00010000 = 16
星期六=(1 << 5),// 00100000 = 32
星期日=(1 << 6),// 01000000 = 64
};

要组合选项,您需要按位运算符:

 时间表时间表=星期一| 星期三;  // 5(= 1 + 4) 

要检查时间表是否等于星期三,可以使用:

  BOOL等于=(时间表==星期三); 

并检查您需要使用的会员资格:

  BOOL containsWednesday =(schedule&Wednesday)!= 0 

Swift中,我们可以为Schedule创建一个struct ,该struct符合表示一组选项的OptionSet协议。 我们使用结构而不是枚举,因为枚举个案是互斥的,因此您不能在Swift中将多个枚举个案合并在一个值中。 在Objective-C中 ,枚举被视为整数,可以采用任何值。

OptionSet协议继承自RawRepresentable ,我们需要声明rawValue。 我们将其声明为Int类型。 对于每个选项,我们都声明一个static let 。 我们使用按位运算符为每个静态成员定义唯一的rawValue

  struct Schedule:OptionSet { 

let rawValue:整数
 静态让星期一= Schedule(rawValue:1 << 0)// 1 
静态let周二= Schedule(rawValue:1 << 1)// 2
static let wednesday = Schedule(rawValue:1 << 2)// 4
静态let周四= Schedule(rawValue:1 << 3)// 8
静态let星期五= Schedule(rawValue:1 << 4)// 16
static let saturday = Schedule(rawValue:1 << 5)// 32
静态让星期日= Schedule(rawValue:1 << 6)// 64
}

如果要为变量分配选项,则非常简单:

 让时间表:Schedule = .monday 

或使用数组创建具有一个或多个成员的选项集:

 让周末:时间表= [.saturday,.sunday] 

请注意, OptionSet并不意味着符合SequenceCollection协议,因此您不能使用count来确定要设置多少位或在for循环中迭代选定的选项。 选项集保持纯整数值。

如果要合并两个选项集,可以执行以下操作:

 让newSchedule = schedule1.union(schedule2) 

您可以使用以下命令检查选项集是否包含某个元素:

  schedule.contains(.saturday) 

并且您可以使用insert(_:)remove(_:)从集合中插入或删除成员。 空选项集由一个空数组[]

Interesting Posts