默认情况下,当你往一个整型常量或变量赋于一个它不能承载的大数时,Swift不会让你这么干的,它会报错。这样,在操作过大或过小的数的时候就很安全了。
例如,Int16
整型能承载的整数范围是-32768
到32767
,如果给它赋上超过这个范围的数,就会报错:
var potentialOverflow = Int16.max // potentialOverflow 等于 32767,这是 Int16 能承载的最大整数 potentialOverflow += 1 // 噢,出错了
对过大或过小的数值进行错误处理让你的数值边界条件更灵活。
当然,你有意在溢出时对有效位进行截断,你可采用溢出运算,而非错误处理。Swfit为整型计算提供了5个&
符号开头的溢出运算符。
- 溢出加法
&+
- 溢出减法
&-
- 溢出乘法
&*
- 溢出除法
&/
- 溢出求余
&%
值的上溢出
下面例子使用了溢出加法&+
来解剖的无符整数的上溢出
var willOverflow = UInt8.max // willOverflow 等于UInt8的最大整数 255 willOverflow = willOverflow &+ 1 // 这时候 willOverflow 等于 0
willOverflow
用Int8
所能承载的最大值255
(二进制11111111
),然后用&+
加1。然后UInt8
就无法表达这个新值的二进制了,也就导致了这个新值上溢出了,大家可以看下图。溢出后,新值在UInt8
的承载范围内的那部分是00000000
,也就是0
。
值的下溢出
数值也有可能因为太小而越界。举个例子:
UInt8
的最小值是0
(二进制为00000000
)。使用&-
进行溢出减1,就会得到二进制的11111111
即十进制的255
。
Swift代码是这样的:
var willUnderflow = UInt8.min // willUnderflow 等于UInt8的最小值0 willUnderflow = willUnderflow &- 1 // 此时 willUnderflow 等于 255
有符整型也有类似的下溢出,有符整型所有的减法也都是对包括在符号位在内的二进制数进行二进制减法的,这在 "按位左移/右移运算符" 一节提到过。最小的有符整数是-128
,即二进制的10000000
。用溢出减法减去去1后,变成了01111111
,即UInt8所能承载的最大整数127
。
来看看Swift代码:
var signedUnderflow = Int8.min // signedUnderflow 等于最小的有符整数 -128 signedUnderflow = signedUnderflow &- 1 // 如今 signedUnderflow 等于 127
除零溢出
一个数除于0i / 0
,或者对0求余数i % 0
,就会产生一个错误。
let x = 1 let y = x / 0
使用它们对应的可溢出的版本的运算符&/
和&%
进行除0操作时就会得到0
值。
let x = 1 let y = x &/ 0 // y 等于 0