When arithmetic is performed on integers, the result will always be an integer. You can assign that result to a long
,
double
, or float
with automatic type conversion, but having started as an int
or long
, the result
will likely not be what you expect.
For instance, if the result of int
division is assigned to a floating-point variable, precision will have been lost before the
assignment. Likewise, if the result of multiplication is assigned to a long
, it may have already overflowed before the assignment.
In either case, the result will not be what was expected. Instead, at least one operand should be cast or promoted to the final type before the
operation takes place.
Noncompliant code example
float twoThirds = 2/3; // Noncompliant; int division. Yields 0.0
long millisInYear = 1_000*3_600*24*365; // Noncompliant; int multiplication. Yields 1471228928
long bigNum = Integer.MAX_VALUE + 2; // Noncompliant. Yields -2147483647
long bigNegNum = Integer.MIN_VALUE-1; //Noncompliant, gives a positive result instead of a negative one.
Date myDate = new Date(seconds * 1_000); //Noncompliant, won't produce the expected result if seconds > 2_147_483
...
public long compute(int factor){
return factor * 10_000; //Noncompliant, won't produce the expected result if factor > 214_748
}
public float compute2(long factor){
return factor / 123; //Noncompliant, will be rounded to closest long integer
}
Compliant solution
float twoThirds = 2f/3; // 2 promoted to float. Yields 0.6666667
long millisInYear = 1_000L*3_600*24*365; // 1000 promoted to long. Yields 31_536_000_000
long bigNum = Integer.MAX_VALUE + 2L; // 2 promoted to long. Yields 2_147_483_649
long bigNegNum = Integer.MIN_VALUE-1L; // Yields -2_147_483_649
Date myDate = new Date(seconds * 1_000L);
...
public long compute(int factor){
return factor * 10_000L;
}
public float compute2(long factor){
return factor / 123f;
}
or
float twoThirds = (float)2/3; // 2 cast to float
long millisInYear = (long)1_000*3_600*24*365; // 1_000 cast to long
long bigNum = (long)Integer.MAX_VALUE + 2;
long bigNegNum = (long)Integer.MIN_VALUE-1;
Date myDate = new Date((long)seconds * 1_000);
...
public long compute(long factor){
return factor * 10_000;
}
public float compute2(float factor){
return factor / 123;
}