This one is probably easy. We know that the operator &+
does modular arithmetic on integers (wraps around), while the operator +
causes an error.
$ swift
1> var x: Int8 = 100
x: Int8 = 100
2> x &+ x
$R0: Int8 = -56
3> x + x
Execution interrupted. Enter Swift code to recover and continue.
What kind of error is this? I can't catch it and I can't turn it in to an optional:
4> do {try x + x} catch {print("got it")}
Execution interrupted. Enter Swift code to recover and continue.
5> try? x + x
Execution interrupted. Enter Swift code to recover and continue.
I'm pretty sure this kind of error is the same kind of error from this Stack Overflow question (a divide-by-zero) but I don't know if this kind of error can be trapped. What simple thing am I missing? Can it be trapped or not? If so, how?
If you want to ensure that arithmetic operations will throw overflow exceptions if an overflow happens, you need to use the checked { ... } code block. When using the checked { ... } code block, if any arithmetic operation causes an overflow, an OverflowException will be thrown, and will need to be catched and handled.
Taking the arithmetic mean of two numbers by adding them and dividing by two, as done in many search algorithms, causes error if the sum (although not the resulting mean) is too large to be represented and hence overflows.
Distinguish between an exception and a runtime error. An exception is thrown and can be caught. A runtime error stops your program dead in its tracks. Adding and getting an overflow is a runtime error, plain and simple. There is nothing to catch.
The point of an operator like &+
is that it doesn't error and it doesn't tell you there was a problem. That is the whole point.
If you think you might overflow, and you want to know whether you did, use static methods like addWithOverflow
. It returns a tuple consisting of the result and a Bool stating whether there was an overflow.
var x: Int8 = 100
let result = x &+ x // -56
x = 100
let result2 = Int8.addWithOverflow(x,x) // (-56, true)
Looks like this has become a non-static method in Swift 5, addingReportingOverflow(_:)
.
So for example,
UInt8.max.addingReportingOverflow(1)
will return (partialValue: 0, overflow: true)
See more on the Int
manual page
And of course the normal arithmetic operators that start with &
to allow overflow without returning overflow reports,
UInt8.max &+ 1
would return 0
as a UInt8
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With