Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does one trap arithmetic overflow errors in Swift?

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?

like image 940
Ray Toal Avatar asked Mar 13 '16 18:03

Ray Toal


People also ask

How do you handle arithmetic overflow?

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.

What causes arithmetic overflow?

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.


2 Answers

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)
like image 90
matt Avatar answered Oct 14 '22 15:10

matt


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

like image 27
grego Avatar answered Oct 14 '22 14:10

grego