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
,在输入位相同的地方设置为0
: 00010100
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
并不意味着符合Sequence
或Collection
协议,因此您不能使用count
来确定要设置多少位或在for
循环中迭代选定的选项。 选项集保持纯整数值。
如果要合并两个选项集,可以执行以下操作:
让newSchedule = schedule1.union(schedule2)
您可以使用以下命令检查选项集是否包含某个元素:
schedule.contains(.saturday)
并且您可以使用insert(_:)
和remove(_:)
从集合中插入或删除成员。 空选项集由一个空数组[]
。