Signature
fmod(float $num1, float $num2): floatPurpose
fmod() gives you the remainder left over when one floating-point number is divided by another. It is the float counterpart of the % operator. Use it when the values can have a fractional part, for example when wrapping an angle, folding a measurement into a repeating range, or checking how much is left after fitting whole units into a length.
The result r satisfies num1 = i * num2 + r for some whole number i. When the divisor is not zero, r carries the same sign as the dividend and its magnitude is smaller than the magnitude of the divisor.
Signature
Parameters and defaults
num1: the dividend, the number being divided.num2: the divisor, the number you divide by.
Neither parameter has a default, so both are required. Integers are accepted and converted to floats when strict typing is off.
Return value and failure cases
The function always returns a float, even if the remainder looks like a whole number. If num2 is 0, the result is NAN (not a number). fmod() does not throw an exception for a zero divisor, so you need to check the result yourself with is_nan() if the divisor might be zero.
Example 1: the sign follows the dividend
The sign of the result comes from the first argument. The sign of the divisor does not change it.
echo fmod(10, 3), "\n";
echo fmod(-10, 3), "\n";
echo fmod(10, -3), "\n";
echo fmod(-10, -3), "\n";1 -1 1 -1
This is the same rule the % operator follows, so negative values do not behave like a mathematical "always positive" modulo.
Example 2: fractions, zero and infinity
With 5.7 and 1.3, four whole divisors fit (4 × 1.3 = 5.2), leaving about 0.5. Because binary floats cannot store most decimals exactly, the raw value may differ from 0.5 in a far decimal place, so the example rounds it before printing.
$r = fmod(5.7, 1.3);
echo round($r, 10), "\n";
var_dump(is_nan(fmod(5, 0)));
var_dump(fmod(5, INF));0.5 bool(true) float(5)
A zero divisor produces NAN, which you detect with is_nan() rather than by comparing with ==. Dividing by infinity leaves the dividend unchanged, because no whole multiple of infinity fits into it.
Example 3: wrapping an angle
Because negative dividends give negative remainders, a wrapping helper usually needs one extra step to shift the result into the range 0 up to (but not including) 360.
function normalizeDegrees(float $degrees): float {
$result = fmod($degrees, 360.0);
return $result < 0 ? $result + 360.0 : $result;
}
echo implode(",", [normalizeDegrees(450), normalizeDegrees(-90), normalizeDegrees(720)]), "\n";90,270,0
The value 450 wraps to 90, -90 wraps to 270, and 720 is exactly two full turns, which leaves 0.
Edge cases
- Zero divisor: returns
NAN, with no exception. - Dividend smaller than the divisor: the dividend comes back unchanged, since no whole multiple fits.
- Exact multiples: the remainder is zero, returned as a float.
- Precision: results are exact for the binary values stored, but those values may not match the decimal numbers you typed. Round before display or comparison.
- Large magnitudes: very large floats lose fractional precision, so the remainder reflects the stored value, not your intended decimal.
Common mistakes
- Using
%for fractional values. The%operator converts both operands to integers first, so5.7 % 1.3is treated as5 % 1. It also throwsDivisionByZeroErrorfor a zero divisor, whilefmod()returnsNAN. - Expecting a non-negative result. A negative dividend gives a negative remainder. Adjust it yourself if you need a positive range.
- Comparing floats with
==. A remainder such as 0.5000000000000004 will fail a strict equality test against 0.5. Use rounding or a small tolerance. - Ignoring
NAN.NANis not equal to anything, including itself. Useis_nan(). - Assuming an integer result. The return type is always
float, so useintdiv()or a cast if you need whole numbers.
Related functions
intdiv()for integer division that discards the remainder.fdiv()for floating-point division that does not throw on a zero divisor.is_nan()to detect the failure value.round(),floor()andabs()for tidying or adjusting remainders.- The
%operator for integer remainders.
Recap
fmod(float $num1, float $num2): float returns the floating-point remainder of num1 / num2. The result takes the sign of num1, is smaller in magnitude than num2, and is NAN when num2 is zero. Reach for it when fractions matter, remember to correct negative results when wrapping, and round before you compare.
Tested examples
echo fmod(10, 3), "\n";
echo fmod(-10, 3), "\n";
echo fmod(10, -3), "\n";
echo fmod(-10, -3), "\n";
1 -1 1 -1
$r = fmod(5.7, 1.3);
echo round($r, 10), "\n";
var_dump(is_nan(fmod(5, 0)));
var_dump(fmod(5, INF));
0.5 bool(true) float(5)
function normalizeDegrees(float $degrees): float {
$result = fmod($degrees, 360.0);
return $result < 0 ? $result + 360.0 : $result;
}
echo implode(",", [normalizeDegrees(450), normalizeDegrees(-90), normalizeDegrees(720)]), "\n";
90,270,0