Today i found one of my programs to be buggy because the implicit cast was not work, better saying it was not working as I expect to be.
i had something like this
long normal = 1000*24*3600*1000;
System.out.println("normal :"+normal);
normal :500.654.080
asking excel the right output of the computation should be 86.400.000.000;
I went to java manual and the max value for the long data type should be 2^63-1, that is: 9.223.372.036.854.780.000
then I tried to force the cast to long, and it seems to work:
long normal = 1000*24*3600*1000;
long explicit = 1000*24*3600*1000l; // 1000l <- letter L used at the end for long
long cast = 1000*(long)(24*3600*1000);
System.out.println("normal :"+normal);
System.out.println("explicit :"+explicit );
System.out.println("cast :"+cast);
normal :500.654.080
explicit :86.400.000.000
cast :86.400.000.000
What I think is happening, is that java does the computation as integer an at a point the integer overflow happens.
Shouldn't Java implicit cast those integers to long?
Isn't it? Conversion from long(8 bytes) to float(4 bytes) is implicit because float save values in the form of exponents. So when we store a long value which ofcourse cannot be stored in a float, JVM converts it into exponential form and then stores it.
Java Type Casting is classified into two types. Widening Casting (Implicit) – Automatic Type Conversion. Narrowing Casting (Explicit) – Need Explicit Conversion.
To convert from left to right (a widening conversion), there is no cast necessary (which is why long to float is allowed).
An implicit cast is a cast that the database server can invoke automatically when it encounters data types that cannot be compared with built-in casts. This type of cast enables the database server to automatically handle conversions between other data types.
In Java, when calculating with integers
, the result will always be an integer
, no matter of the type of the variable you use to assign the result.
Assigning one (or all) of the numeric literals as a Long is the way to go, as you have found out yourself already:
long implicit = 1000L*24*3600*1000;
EDIT: as noted in the comments, operands in Java are evaluated from left to right, so at least the first operand on the left should be assigned as Long
When you use numbers without the L
postfix Java will interpret this as integers
, the default number in the language. The calculations will always be done in int
as well, so you'll experience the overflow.
If you cast or use an explicit long
value all the values in the calculation are 'promoted'/widened to long values. This is described here in the language specification:
http://docs.oracle.com/javase/specs/jls/se8/html/jls-5.html#jls-5.6.2
The expression is evaluated before the assignment to the variable (which has type long
), so Java isn't aware of the overflow and doesn't promote anything in your first example.
java implict long cast behaviour
There is no 'implicit long cast behaviour' in Java. You have to enforce it yourself, by using a long literal or a (long)
typecast. Your code doesn't do that, so the value is calculated in int
precision. If you want long
precision, do one of the following:
long normal = 1000L*24*3600*1000;
long normal = 1000*24L*3600*1000;
long normal = 1000*24*3600L*1000;
long normal = 1000*24*3600*1000L;
long normal = (long)1000*24*3600*1000;
long normal = 1000*(long)24*3600*1000;
long normal = 1000*24*(long)3600*1000;
long normal = 1000*24*3600*(long)1000;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With