How Modulo Handles Negative Numbers in C

In the C programming language, the behavior of the modulo operator—formally designated as the remainder operator (%)—with negative operands is strictly defined by modern revisions of the standard (C99 and later). Modern C dictates that integer division always truncates toward zero, which inherently forces the remainder operator to adopt the sign of the dividend (the left-hand operand), irrespective of the sign of the divisor (the right-hand operand). This article outlines the governing algebraic identity, explains how truncation toward zero determines the result, and demonstrates how expressions evaluate using negative integers.

The Governing Identity

According to modern C standards (including C99, C11, C17, and C23), integer division and the remainder operator are bound by the following algebraic relationship:

(a / b) * b + a % b == a

This equation must hold true for any integer values of a and b, provided b is not zero (division by zero results in undefined behavior).

Truncation Toward Zero

In modern C, integer division (/) truncates toward zero. This means any fractional part of the quotient is discarded. For example:

  • 7 / 3 evaluates to 2
  • -7 / 3 evaluates to -2
  • 7 / -3 evaluates to -2
  • -7 / -3 evaluates to 2

Because the quotient is rounded toward zero rather than toward negative infinity, the sign of the remainder a % b is determined entirely by the dividend a.

Sign Determination Rules

When using the % operator with non-zero results:

  1. The sign of the result matches the sign of the dividend (a). If the left operand is negative, the remainder is negative. If the left operand is positive, the remainder is positive.
  2. The sign of the divisor (b) is irrelevant. Changing the sign of the right operand does not change the result of the operation.

Evaluation Examples

  • 7 % 3 evaluates to 1 (7 / 3) * 3 + (7 % 3) => 2 * 3 + 1 = 7
  • -7 % 3 evaluates to -1 (-7 / 3) * 3 + (-7 % 3) => -2 * 3 + (-1) = -7
  • 7 % -3 evaluates to 1 (7 / -3) * -3 + (7 % -3) => -2 * -3 + 1 = 7
  • -7 % -3 evaluates to -1 (-7 / -3) * -3 + (-7 % -3) => 2 * -3 + (-1) = -7

Historical Context

In the original ANSI/ISO C standard (C89/C90), the behavior of division with negative operands was implementation-defined; compilers were permitted to round either toward zero or toward negative infinity. Consequently, the sign of a % b depended on the compiler implementation if either operand was negative. Since the introduction of C99, truncation toward zero became mandatory, eliminating platform-dependent ambiguity and standardizing the remainder's sign across all compliant modern C compilers.