-1

I want to write a function that resizes a 2D array to the given parameters. Its a general resize array:

public static int[][] resize(int[][] source, int newWidth, int newHeight) {

        int[][] newImage=new int[newWidth][newHeight];
        double scale=newWidth/source.length;
        for (int j=0;j<newHeight;j++)
            for (int i=0;i<newWidth;i++)
                newImage[i][j]=source[(int)(i/scale)][(int)(j/scale)];
        return newImage;

The code above has no problems, it works great for integer resizing. The problem arises however, when I use the resize function to resize an array by a factor of 0.5.

int[][] newImage=new int[source.length][source.length];
newImage=resize(source,source.length/2,source[0].length/2);
        return newImage;

Then everything goes crazy. I get an outofboundserrorexception of like 2147483647. The problem lies in the double scale variable in the first function and the type casting I used in the first function in the last line. Any ideas for fixes?

Note: source.length is the width (columns) of the array, and source[0].length is the height(rows).

3
  • 3
    2147483647 just happens to be 2^31-1 (the maximum value for a signed int in java). Coincidence? I think not. Happy coding. Commented Oct 9, 2010 at 23:22
  • possible duplicate of Java Array Manipulation Commented Oct 9, 2010 at 23:33
  • What is missing from SO is a set of generic answers that explains to student programmers how to debug programs. Commented Oct 10, 2010 at 2:25

3 Answers 3

2

The scale variable is of type double. You probably expect the following:

int newWidth = 5;
int sourceLength = 10;
double scale = newWidth / sourceLength;
// what is `scale` now?

The surprising thing is that scale is now 0.0. This is because dividing an int by an int always results in an int again.

To get the result you want, you have to write:

double scale = ((double) newWidth) / sourceLength;

or

double scale = 1.0 * newWidth / sourceLength;

Then the division takes place with a double and an int, and the result will be a double, in this case the expected 0.5.

Sign up to request clarification or add additional context in comments.

Comments

1

Explanation:

  1. The expression 1/2 is an integer division. It yields 0.
  2. Assigning 0 to a double will turn it into 0.0
  3. 1 / 0.0 is a floating point division, and yields Double.POSITIVE_INFINITY.
  4. casting Double.POSITIVE_INFINITY to int yields Integer.MAX_VALUE.

Dirty fix:

double scale = ((double)newWidth) / source.length;

That code is not very efficient, as it constantly converts between doubles and ints. You can stick with ints by doing:

newImage[i][j]=source[i * source.length / newWidth][j * source.length / newWidth];

That solution however will overflow if newWidth * source.length > Integer.MAX_VALUE but I suspect you won't be working with matrices that big.

Comments

0

Strangely enough, this works:

String[] sArray = new String[10];
sArray[0] = "Zero";
sArray[1] = null;
sArray[2] = "Two";
sArray[3] = "Three";
sArray[4] = null;
sArray[5] = "Five";
sArray[6] = "Six";
sArray[7] = null;
sArray[8] = null;
sArray[9] = null;
assertTrue(sArray.length == 10);  // part of JUnit - not needed for program

for (int i = sArray.length - 1; i > -1; i--) {
  if (sArray[i] == null ) {
    // has nothing to do with the array element #
    sArray = ((String[]) ArrayUtils.removeElement(sArray, null));
  }
}

assertTrue(sArray.length == 5);  // part of JUnit - not needed for program

The trick was in specifying null as the second parameter in the removeElement call. Not intuitive at all! I expected to pass the array element I wanted to remove, but that did not change the size of the array. If you want to do multiple conditions, put them in the if statement, then null that array element before calling removeElement.

Example:

  // any of these conditions will cause the array element to be removed.
  if ((sArray[i] == null ) || ( sArray[i].equals("") ) || ( sArray[i].equals("deleteMe")) ) {
    sArray[i] = null;
    sArray = ((String[]) ArrayUtils.removeElement(sArray, null));
  }

Anyone have additional insights on this, and why it works like this, and why I've never seen it, though I've searched many times!!!!

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.