Details

Type: Bug Detection

Status: Active

Resolution: Unresolved

Labels:

Message:Cast one of the operands of this (divisionmultiplication) operation to a "xxx".

Default Severity:Minor

Impact:Low

Likelihood:Low

Default Quality Profiles:Sonar way

Targeted languages:C, C++, ObjectiveC

Covered Languages:C#, Java

Irrelevant for Languages:Swift

Remediation Function:Constant/Issue

Constant Cost:5min

Analysis Scope:Main Sources, Test Sources

CERT:NUM50J., INT18C.

CWE:CWE190

SANS Top 25:Risky Resource Management

FindBugs:ICAST_IDIV_CAST_TO_DOUBLE, ICAST_INTEGER_MULTIPLY_CAST_TO_LONG, ICAST_INT_2_LONG_AS_INSTANT

PCLint:653, 1653

ReSharper:PossibleLossOfFraction
Description
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 floatingpoint 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_VALUE1; //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_VALUE1L; // 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_VALUE1; 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; }
See
 MITRE, CWE190  Integer Overflow or Wraparound
 CERT, NUM50J.  Convert integers to floating point for floatingpoint operations
 CERT, INT18C.  Evaluate integer expressions in a larger size before comparing or assigning to that size
 SANS Top 25  Risky Resource Management
Attachments
Issue Links
 is implemented by

CPP1614 Rule: Math operands should be cast before assignment
 Open

SONARJAVA774 Rule: S2184 Math operand should be cast before assignement
 Closed
 is related to

SONARJAVA3479 FP in S2184 when return is in another scope
 Closed
 relates to

RSPEC848 There shall be no explicit floatingintegral conversions of a "cvalue" expression.
 Active
1.

C#: Results of integer division should not be assigned to floating point variables  RSPEC3517  Active  Unassigned  
2.

CFamily  RSPEC849  Active  Unassigned 