## 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

### Standards

- CWE - 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
- STIG Viewer - Application Security and Development: V-222612 - The application must not be vulnerable to overflow attacks.