6

I have something like this in my app:

def something(x: Int, y: Int) Z {

    (x / y)
}

Now, if the someval is not a number (meaning that either x or y is equal to 0), then I'd like Z to just become 0 instead of displaying an error ([ArithmeticException: Division by zero])

I know I can do:

Try(someVale) orElse Try(0)

However, that'll give me Success(0) whereas I'd just like for it to give me a 0 in that case.

Maybe there's something like if ArithmeticException then 0 in Scala or something to remove the "Success" and parenthesis. Can someone shed some light please?

Valy Dia
  • 2,781
  • 2
  • 12
  • 32
goo
  • 2,230
  • 4
  • 32
  • 53
  • Just in case: is it just an example of unavoidable exception or the problem is literally in "divide by zero"? – senia Jan 15 '14 at 05:34

3 Answers3

15

I think I would look to :

def something(x: Int, y:Int) = if ( y != 0) x/y else 0
senia
  • 37,745
  • 4
  • 88
  • 129
guest
  • 159
  • 2
  • 2
    +1 - This is the only reasonable answer. Catching an arithmetic exception with lots of extra machinery and huge runtime cost instead of executing a single simple conditional is madness! – Rex Kerr Jan 15 '14 at 00:15
  • 2
    that depends on how often y==0; if y == 0 is rare then typically try-catch is free whereas if(y != 0) has constant cost in all cases. – Ron Reynolds Jul 18 '18 at 19:43
12

I'm assuming "divide by zero" is just an example and you can't avoid throwing an exception. When you can avoid throwing an exception you should do it like in this answer.

You could use getOrElse method on Try instead of orElse:

def something(x: Int, y: Int) = Try(x/y).getOrElse(0)

In case you want to recover only on ArithmeticException you could use recover method and get:

def something(x: Int, y: Int) =
  Try(x/y).recover{ case _: ArithmeticException => 0 }.get

With method get you'll get an exception if Try is Failure, but recover allows you to convert Failure to Success.

You could also convert your Try to Option to return "no result" without showing exception:

def something(x: Int, y: Int): Option[Int] = Try(x/y).toOption
Community
  • 1
  • 1
senia
  • 37,745
  • 4
  • 88
  • 129
4

Just catch the exception and return 0 is the simplest way.

def something(x: Int, y: Int) = try {
    (x / y)
  } catch {
    case ae: java.lang.ArithmeticException => 0
  }

Run it:

scala> something(1,0)
res0: Int = 0

scala> something(2,1)
res1: Int = 2
om-nom-nom
  • 62,329
  • 13
  • 183
  • 228
Brian
  • 20,195
  • 6
  • 34
  • 55