Search code examples
javatypecasting-operator

Why Type Casting of larger variable to smaller variable results in modulo of larger variable by the range of smaller variable


Recently,while I was going through typecasting concept in java, I have seen that type casting of larger variable to smaller variable results in the modulo of larger variable by the range of smaller variable.Can anyone please explain this in detail why this is the case and is it true for any explicit type conversion?.

     class conversion {
    public static void main(String args[]) 
    {
        double a = 295.04;
        int  b = 300;
        byte c = (byte) a;
        byte d = (byte) b;
        System.out.println(c + " "  + d);
    } 
}

The above code gives the answer of d as 44 since 300 modulo 256 is 44.Please explain why this is the case and also what happens to the value of c?


Solution

  • It is a design decision that goes all the way back the the C programming language and possibly to C's antecedents too.

    What happens when you convert from a larger integer type to a smaller integer type is that the top bits are lopped off.

    Why? Originally (and currently) because that is what hardware integer instructions support.

    The "other" logical way to do this (i.e. NOT the way that Java defines integer narrowing) would be to convert to that largest (or smallest) value representable in the smaller type; e.g.

        // equivalent to real thin in real java
        // b = (byte) (Math.max(Math.min(i, 127), -128))
    

    would give +127 as the value of b. Incidentally, this is what happens when you convert a floating-point value to an integer value, and the value is too large. That is what is happening in your c example.


    You also said:

    The above code gives the answer of d as 44 since 300 modulo 256 is 44.

    In fact, the correct calculation would be:

    int d = ((b + 128) % 256) - 128;
    

    That is because the range of the Java byte type is -128 to +127.


    For completeness, the above behavior only happens in Java when the larger type is an integer type. If the larger type is a floating point type and the smaller one is an integer type, then a source value that is too large or too small (or an infinity) gets converted to the largest or smallest possible integer value for the target type; e.g.

    double x = 1.0e200;
    int i = (int) x;   // assigns 'Integer.MAX_VALUE' to 'i'
    

    And a NaN is converted to zero.

    Reference: