## Why is this an issue?

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;
}

## Resources

- MITRE, CWE-190 - Integer Overflow or Wraparound
- CERT, NUM50-J. - Convert integers to floating point for floating-point operations
- CERT, INT18-C. - Evaluate integer expressions in a larger size before comparing or
assigning to that size
- SANS Top 25 - Risky Resource Management