Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-6535058

Inconvenient to detect overflow while multiplying two long values

    XMLWordPrintable

    Details

    • Type: Enhancement
    • Status: Closed
    • Priority: P5
    • Resolution: Not an Issue
    • Affects Version/s: 7
    • Fix Version/s: None
    • Component/s: core-libs
    • Labels:
    • Subcomponent:
    • CPU:
      x86
    • OS:
      windows_xp

      Description

      A DESCRIPTION OF THE REQUEST :
      The Java language does not allow to detect overflow while the following code:

          long a = 7000000000L, b = 5000000000L;
          long c = a*b; // OVERFLOW!

      Sometimes it leads to serious problems. Let's consider the following example:

      public static SomeMyMatrix createMatrix(long width, long height) {
          long size = width * height; // ERROR! Overflow possible for illegal width and height.
          // then we create a file with the calculated number of bytes and use it for storing the matrix width*height
          ...
      }

      Here we tries to create a matrix that can contain more than 2^31 bytes. There are many ways to do this; for example, such a matrix can be stored in a large mapped file. The important thing is that both matrix width and height may be, theoretically, greater than 2^31 and cannot be described by "int" type.

      How, in this situation, to calculate the matrix size: the product width*height? Of course, when we passes correct argument to this method, the width*height value will not be too high. Today it can be several gigabytes; tomorrow, maybe, it will be several terabytes. But how can I detect ILLEGAL width and height arguments?

      For example, if I'll pass width=2^32 and height=2^32, the calculated size will be zero! The corresponding matrix will be probably created successfully, but will not work, because it's size!=width*height.

      If width and height are "int" values, the solution is very simple: I should check (long)a*(long)b. For "long" type, this technique does not work. If I'll try to use "double" type - (double)a*(double)b - the result may be incorrect because the precision of double values is less than 64 bits. Namely, if I'll write

         if ((double)width*(double)height>Long.MAX_VALUE)
             throw new IllegalArgumentException(...)

      this check may "skip" (not detect) some illegal (too high) width and height because of rounding. Another possible solution is using BigDecimal, but it seems too slow and "hard" method for such simple problem.

      I've created a simple function "longMul(long a, long b)", that allows to resolve this issue. Please see the attached source code. In a case of overflow, it returns the "signal" result Long.MIN_VALUE.

      Could you include this or equivalent function in your standard Math class?

      JUSTIFICATION :
        Too complex code allowing to detect overflow while "long" multiplication.

        Attachments

          Issue Links

            Activity

              People

              Assignee:
              darcy Joe Darcy
              Reporter:
              ryeung Roger Yeung (Inactive)
              Votes:
              0 Vote for this issue
              Watchers:
              0 Start watching this issue

                Dates

                Created:
                Updated:
                Resolved:
                Imported:
                Indexed: