Search code examples
scalabigintegerinteger-overflow

Common practice how to deal with Integer overflows?


What's the common practice to deal with Integer overflows like 999999*999999 (result > Integer.MAX_VALUE) from an Application Development Team point of view?

One could just make BigInt mandatory and prohibit the use of Integer, but is that a good/bad idea?


Solution

  • If it is extremely important that the integer not overflow, you can define your own overflow-catching operations, e.g.:

    def +?+(i: Int, j: Int) = {
      val ans = i.toLong + j.toLong
      if (ans < Int.MinValue || ans > Int.MaxValue) {
        throw new ArithmeticException("Int out of bounds")
      }
      ans.toInt
    }
    

    You may be able to use the enrich-your-library pattern to turn this into operators; if the JVM manages to do escape analysis properly, you won't get too much of a penalty for it:

    class SafePlusInt(i: Int) {
      def +?+(j: Int) = { /* as before, except without i param */ }
    }
    implicit def int_can_be_safe(i: Int) = new SafePlusInt(i)
    

    For example:

    scala> 1000000000 +?+ 1000000000
    res0: Int = 2000000000
    
    scala> 2000000000 +?+ 2000000000
    java.lang.ArithmeticException: Int out of bounds
        at SafePlusInt.$plus$qmark$plus(<console>:12)
        ...
    

    If it is not extremely important, then standard unit testing and code reviews and such should catch the problem in the large majority of cases. Using BigInt is possible, but will slow your arithmetic down by a factor of 100 or so, and won't help you when you have to use an existing method that takes an Int.