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).