Swift learning part 26 - 高级运算符

作为基本运算符的补充,Swift 提供了一些对数值进行复杂运算的高级运算符。它们包含了在 C 和 Objective-C 中已经被大家所熟知的位运算符和移位运算符。

与 C 的算术运算符不同,Swift 中算术运算符默认不会溢出。溢出行为都会作为错误被捕获。想要允许溢出行为,可以使用 Swift 中另一套默认支持溢出的运算符,比如溢出加法运算符 &+。所有这些溢出运算符都是以 & 符号开始的。

定义结构体、类和枚举时,为这些自定义类型也提供 Swift 标准的运算符将会非常有用。Swift 简化了这些运算符的定制实现,运算符也会针对不同类型使用对应的实现。

你不会被限制在预定义的运算符里。Swift 允许你自由地定义中缀、前缀、后缀和赋值运算符,以及相对应的优先级和结合性。这些运算符可以像预定义的运算符一样使用,你甚至可以扩展已有类型来支持自定义的运算符。

位运算符

位运算符可以操作数据结构中每一个独立的比特位。它们通常被用在底层开发中,比如图形编程和创建设备驱动。位运算符在处理外部资源的原始数据时也非常有用,比如为自定义的通信协议的数据进行编码和解码。

Swift 支持 C 里面所有的位运算符。

按位取反运算符

按位取反运算符( ~ )是一个前缀运算符,对一个数值的全部比特位进行取反:

let initialBits: UInt8 = 0b00001111
let invertedBits = ~initialBits // 等于 0b11110000

使用二进制值 00001111 初始化了一个 UInt8 类型的整数 initialBits,前四位全是 0 ,后四位都是 1 。使用按位取反运算符创建一个新的常量名为 invertedBits ,initialBits 所有位都被取反,invertedBits 的值是 11110000。

按位与运算符

按位与运算符( & )可以对两个数的比特位进行合并。它会返回一个新的数,只有当两个数的对应比特位位都是 1 的时候,新数对应的比特位才为 1。

在下面的例子中, firstSixBits 和 lastSixBits 的中间四个位都为 1 。按位与可以把它们合并为一个新值 00111100:

let firstSixBits: UInt8 = 0b11111100
let lastSixBits: UInt8 = 0b00111111
let middleFourBits = firstSixBits & lastSixBits // 等于 0b00111100

按位或运算符

按位或运算符( | )可以对两个比特位进行比较,然后返回一个新的数,只要两个操作位任一为 1,新数对应的比特位就为 1。

在下面的例子中, someBits 和 moreBits 在不同的位设置了 1 。位或运算符把它们合并为 11111110:

let someBits: UInt8 = 0b10110010
let moreBits: UInt8 = 0b01011110
let combinedbits = someBits | moreBits // 等于 0b11111110

按位异或运算符

按位异或运算符( ^ )可以对两个数的比特位进行比较,当两个操作数的对应比特位不相同时,薪数对应的比特位就为 1。

在下面的例子中, firstBits 和 otherBits 的值有一位设置为 1 ,而对方设置为 0 。按位异或运算符会将这两个位上的值设置为 1 , firstBits 和 otherBits 其他位都设置为了 0 :

let firstBits: UInt8 = 0b00010100
let otherBits: UInt8 = 0b00000101
let outputBits = firstBits ^ otherBits // 等于 0b00010001

按位左移、右移运算符

按位左移运算符(<<)和 按位右移运算符(>>)可以对一个数的所有位进行指定位数的左移和右移,但是需要遵守下面定义的规则:

将一个整数左移一位,等价于将这个数乘以 2,同样地,将一个整数右移一位,等价于将这个数除以 2。

无符号整数的移位运算

对无符号整数的移位规则如下:

已经存在的比特位按指定的位数进行左移和右移。
任何因移动而超出整型存储范围的位都会被丢弃。
用 0 来填充向左或向右移动后产生的空白位。

这种方法称为逻辑移位。

下面的代码展示了 Swift 中的移位运算:

let shiftBits: UInt8 = 4 // 即二进制的 0b00000100
var shiftedBits = shiftBits << 1 // 0b00001000
shiftedBits = shiftBits << 2 // 0b00010000
shiftedBits = shiftBits << 5 // 0b10000000
shiftedBits = shiftBits << 6 // 0b00000000
shiftedBits = shiftBits >> 2 // 0b00000001

可以使用移位操作对其他的数据类型进行编码和解码:

let pink: UInt32 = 0xCC6699
let redComponent = (pink & 0xFF0000) >> 16 // redComponent 是 0xCC, 即 204
let greenComponent = (pink & 0x00FF00) >> 8 // greenComponent 是 0x66, 即 102
let blueComponent = pink & 0x0000FF // blueComponent 是 0x99, 即 153

这个示例使用了一个命名为 pink 的 UInt32 常量来存储层叠样式表(CSS)中粉色的颜色值。该 CSS 的颜色值 #CC6699 , 在 Swift 中表示为十六进制 0xCC6699 。然后利用按位与运算符和位右移运算符从这个颜色值中分解出 红 CC、绿 66 以及 蓝 99 三个部分。

红色部分通过对 0xCC6699 和 0xFF0000 进行按位与运算得到 0xCC0000。然后,再将这个数按向右移动 16 位得到 0xCC,也就是十进制数值的 204。

同样的,绿色部分通过对 0xCC6699 和 0x00FF00 进行按位与运算得到 0x006600。然后将这个数向右移动 8 位,得到 0x66,也就是十进制数值的 102。

最后&

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值