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 == aThis 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 / 3evaluates to2-7 / 3evaluates to-27 / -3evaluates to-2-7 / -3evaluates to2
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:
- 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. - 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 % 3evaluates to1(7 / 3) * 3 + (7 % 3) => 2 * 3 + 1 = 7-7 % 3evaluates to-1(-7 / 3) * 3 + (-7 % 3) => -2 * 3 + (-1) = -77 % -3evaluates to1(7 / -3) * -3 + (7 % -3) => -2 * -3 + 1 = 7-7 % -3evaluates 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.