Possible Loss Of Fraction
ID |
csharp.possible_loss_of_fraction |
Severity |
low |
Remediation Complexity |
trivial |
Remediation Risk |
low |
Remediation Effort |
low |
Resource |
Reliability |
Language |
CSharp |
Tags |
reliability, suspicious-operator |
Description
Reports local variable declarations of a floating-point type (float, double
or decimal) whose initializer is an integer division. In C# the expression is
evaluated <em>before</em> being widened to the declared type, so an integer
division truncates toward zero and the fractional part is lost.
Rationale
double x = 1 / 2; assigns 0.0, not 0.5, because the right-hand side is an
integer expression. The widening to double happens only after truncation. The
fix is to make one of the operands a floating-point value, either by literal
suffix (1.0 / 2) or by an explicit cast ((double)a / b).
int a = 5, b = 2;
double bad = a / b; // FLAW — integer division then widen, bad == 2.0
double ok1 = (double)a / b; // OK
double ok2 = a / 2.0; // OK
double ok3 = 5.0 / 2; // OK — at least one operand is double
float pct = 50 / 100; // FLAW — pct == 0.0
float pctOk = 50f / 100; // OK — pct == 0.5
Remediation
Cast at least one operand to the target floating-point type, or use a literal of
that type (1.0, 1f, 1m).