5

I have defined array gx, array arr to be short type. but why the operation at left may end up with int type and I must cast it into short? the compiler error is possible lossy conversion from int to short.

this is my code.

public PixImage sobelEdges() {

short gy=0;
for(int x=1;x<width-1;x++){
    for(int y=1;y<height-1;y++){
       // if(x=){
            for(int z=0;z<3;z++){
            gx[x][y][z]=arr[x-1][y-1][z]-arr[x+1][y-1][z]+2*arr[x-1][y][z]-2*arr[x+1][y][z]+arr[x-1][y+1][z]-arr[x+1][y+1][z];

            }
       // }    
    }     
}   
return this;
// Don't forget to use the method mag2gray() above to convert energies to
// pixel intensities.

}

Is that because the so called unbox? so that means every time I made a operation I need to cast?

Luiggi Mendoza
  • 85,076
  • 16
  • 154
  • 332
Christy Lin
  • 105
  • 1
  • 1
  • 7
  • `int` is bigger than `short`. Loss of bits may occur. – Robert Harvey Jun 11 '14 at 23:02
  • The compiler is probably noticing that you're multiplying `short` values together and storing the result into a `short`. There is a chance that the result of the multiplication will be larger than a `short`. This has nothing to do with Boxing/Unboxing. That refers to implicit conversion from `int` to `Integer`, for example. – bstar55 Jun 11 '14 at 23:06
  • 1
    Try casting your 2's to shorts. (short)2*arr... – bstar55 Jun 11 '14 at 23:07
  • thnx! a lot need to learn – Christy Lin Jun 11 '14 at 23:27

1 Answers1

12

It's not unboxing; it's "binary numeric promotion". Section 5.6.2 of the JLS states:

When an operator applies binary numeric promotion to a pair of operands, each of which must denote a value that is convertible to a numeric type, the following rules apply, in order:

  1. If any operand is of a reference type, it is subjected to unboxing conversion (§5.1.8).

  2. Widening primitive conversion (§5.1.2) is applied to convert either or both operands as specified by the following rules:

    • If either operand is of type double, the other is converted to double.

    • Otherwise, if either operand is of type float, the other is converted to float.

    • Otherwise, if either operand is of type long, the other is converted to long.

    • Otherwise, both operands are converted to type int.

and

Binary numeric promotion is performed on the operands of certain operators:

  • The multiplicative operators *, /, and % (§15.17)

  • The addition and subtraction operators for numeric types + and - (§15.18.2)

  • The numerical comparison operators <, <=, >, and >= (§15.20.1)

  • The numerical equality operators == and != (§15.21.1)

  • The integer bitwise operators &, ^, and | (§15.22.1)

  • In certain cases, the conditional operator ? : (§15.25)

(emphasis mine)

When those values are added/multiplied, they are promoted to int before the math is done. At the end, you can cast back to short before assigning back to the array.

gx[x][y][z] = (short) (arr[x-1][y-1][z]-arr[x+1][y-1][z]+2*arr[x-1][y][z]
    -2*arr[x+1][y][z]+arr[x-1][y+1][z]-arr[x+1][y+1][z]);

You will need to cast it back every time you operate with primitive data types that are smaller than int, such as in your short example.

rgettman
  • 176,041
  • 30
  • 275
  • 357