转载请声明出处:http://blog.csdn.net/jinnchang/article/details/43481771
1、位运算符
位操作符通常在诸如图像处理和创建设备驱动等底层开发中使用,使用它可以单独操作数据结构中原始数据的比特位。在使用一个自定义的协议进行通信的时候,运用位运算符来对原始数据进行编码和解码也是非常有效的。
【扩展】无符号、有符号整型数的二进制表示如下所述:
有符号整型中的最高位是符号位,0代表正数,1代表负数。
有符号正数的存储方式和无符号整型原理一样的。有符号负数的存储方式为2的n次方减去它的绝对值,n为数值位数。负数的这种编码方式称为二进制补码。
如 +4 表示为 0b00000100;-4 表示为 0b11111100,即 128(2的7次方) - 4 = 124。
// 1、按位取反运算符(~)
let initialBits: UInt8 = 0b00001111
let invertedBits = ~initialBits // 0b11110000
// 2、按位与运算符(&)
let firstSixBits: UInt8 = 0b11111100
let lastSixBits: UInt8 = 0b00111111
let middleFourBits = firstSixBits & lastSixBits // 0b00111100
// 3、按位或运算符(|)
let someBits: UInt8 = 0b10110010
let moreBits: UInt8 = 0b01011110
let combinedbits = someBits | moreBits // 0b11111110
// 4、按位异或运算符(^)
let firstBits: UInt8 = 0b00010100
let otherBits: UInt8 = 0b00000101
let outputBits = firstBits ^ otherBits // 0b00010001
// 5、按位左移运算符(<<):相当于乘以2
// 无符号整型移位
let leftBits: UInt8 = 0b00000100
leftBits << 1 // 0b00001000
leftBits << 6 // 0b00000000
// 有符号整型移位
let plusLeftBits: Int8 = 0b00000100
plusLeftBits << 1 // 0b00001000
let minusLeftBits: Int8 = 0b11111100
minusLeftBits << 1 // 0b11111000
// 6、按位右移运算符(>>):相当于除以2
// 无符号整型移位
let rightBits: UInt8 = 0b00000100
rightBits >> 2 // 0b00000001
rightBits >> 3 // 0b00000000
// 有符号整型移位(右移时使用符号位填充空白)
let plusRightBits: Int8 = 0b00000100
plusRightBits >> 2 // 0b00000001
let minusRightBits: Int8 = 0b11111100
minusRightBits >> 1 // 0b11111110
2、溢出运算符
默认的整型数是有范围的,如果将变量或者常量赋值超过范围会报溢出错误。但是如果有意在溢出时对有效位进行截断,可以采用溢出运算符(&+、&-、&*、&/、&%)。
// 1、上溢出
var willOverflow = UInt8.max // 0b11111111
willOverflow = willOverflow &+ 1 // 0b00000000
var willOverflow = Int8.max // 0b01111111
willOverflow = willOverflow &+ 1 // 0b10000000
// 2、下溢出
var willUnderflow = UInt8.min // 0b00000000
willUnderflow = willUnderflow &- 1 // 0b11111111
var willUnderflow = Int8.min // 0b10000000
willUnderflow = willUnderflow &- 1 // 0b01111111
// 3、除零
let x = 1
let y = x &/ 0 // 0
let z = x &% 0 // 0
3、函数运算符
(1)运算符重载
让已有的运算符对自定义的类或结构进行运算,称为运算符重载。
struct Vector2D {
var x = 0.0, y = 0.0
}
// 1、定义和实现中置运算
func + (left: Vector2D, right: Vector2D) -> Vector2D {
return Vector2D(x: left.x + right.x, y: left.y + right.y)
}
let vector = Vector2D(x: 3.0, y: 1.0)
let anotherVector = Vector2D(x: 2.0, y: 4.0)
let combinedVector = vector + anotherVector
func == (left: Vector2D, right: Vector2D) -> Bool {
return (left.x == right.x) && (left.y == right.y)
}
func != (left: Vector2D, right: Vector2D) -> Bool {
return !(left == right)
}
let twoThree = Vector2D(x: 2.0, y: 3.0)
let anotherTwoThree = Vector2D(x: 2.0, y: 3.0)
if twoThree == anotherTwoThree {
println("These two vectors are equivalent.")
}
// prints "These two vectors are equivalent."
// 2、使用 prefix 定义和实现前置运算
prefix func - (vector: Vector2D) -> Vector2D {
return Vector2D(x: -vector.x, y: -vector.y)
}
let positive = Vector2D(x: 3.0, y: 4.0)
let negative = -positive
// 3、使用 postfix 定义和实现后置运算
postfix func -- (vector: Vector2D) -> Vector2D {
return Vector2D(x: vector.x - 1.0, y: vector.y - 1.0)
}
let positive = Vector2D(x: 3.0, y: 4.0)
let negative = positive--
// 4、定义和实现组合赋值运算
func += (inout left: Vector2D, right: Vector2D) {
left = left + right
}
var original = Vector2D(x: 1.0, y: 2.0)
let vectorToAdd = Vector2D(x: 3.0, y: 4.0)
original += vectorToAdd
注意:默认的赋值运算符(=)是不可重载的。三目条件运算符(a ? b : c)也是不可重载。
(2)自定义新的运算符
新的运算符需要在全局域使用 operator 关键字声明,可以定义为前置、中置或者后置。
prefix operator +++ {}
prefix func +++ (inout vector: Vector2D) -> Vector2D {
vector += vector
return vector
}
var toBeDoubled = Vector2D(x: 1.0, y: 4.0)
let afterDoubling = +++toBeDoubled
(3)优先级和结合性
可以为自定义的中置运算符指定优先级和结合性。
优先级(precedence)默认为100。
结合性(associativity)的可取的值:left、right 和 none,默认为 none。左结合运算符跟其他优先级相同的左结合运算符写在一起时,会跟左边的操作数结合。同理,右结合运算符会跟右边的操作数结合。而非结合运算符不能跟其他相同优先级的运算符写在一起。
infix operator +- { associativity left precedence 140 }
func +- (left: Vector2D, right: Vector2D) -> Vector2D {
return Vector2D(x: left.x + right.x, y: left.y - right.y)
}
let firstVector = Vector2D(x: 1.0, y: 2.0)
let secondVector = Vector2D(x: 3.0, y: 4.0)
let plusMinusVector = firstVector +- secondVector
4、结语
文章最后更新时间:2015年4月3日15:59:58。
欲了解更细致的请参考官方文档:Advanced Operators