Python math.remainder(): IEEE 754 Remainder Function

The math.remainder(x, y) function computes the IEEE 754-2008 standard remainder of x with respect to y, defined as r = x − (n × y), where n is the integer nearest to x / y. Unlike Python's modulo operator (%) or math.fmod(), the result is strictly bounded within the symmetric range [−|y|/2, |y|/2].

Ties to Even: If x / y lies exactly halfway between two consecutive integers (e.g. 1.5 or 2.5), n is chosen to be the nearest even integer (banker's rounding).

Syntax & Parameters 🔝

The math.remainder() function was introduced in Python 3.7 as part of the standard math module:

import math

r = math.remainder(x, y)
Parameter Type Description
x float or int Required. The numerator (dividend).
y float or int Required. The denominator (divisor). Must not be zero.
Return Value float The IEEE 754 remainder within [−|y|/2, |y|/2].
ValueError Exception Raised when y == 0 or when x is infinite.
TypeError Exception Raised when passing non-numeric arguments (strings, lists, None).

Basic Usage & Nearest-Integer Mechanics 🔝

To understand why math.remainder(12, 7) produces -2.0 while 12 % 7 produces 5, look at the quotient:

  1. Compute x / y = 12 / 7 ≈ 1.714.
  2. The integer closest to 1.714 is 2 (not 1).
  3. Calculate r = x - (n * y) = 12 - (2 * 7) = 12 - 14 = -2.0.
import math

print("remainder(12, 7):", math.remainder(12, 7))  # 12 / 7 = 1.71 -> n=2 -> 12 - 14 = -2.0
print("remainder(12, 5):", math.remainder(12, 5))  # 12 / 5 = 2.40 -> n=2 -> 12 - 10 =  2.0
print("remainder(13, 7):", math.remainder(13, 7))  # 13 / 7 = 1.86 -> n=2 -> 13 - 14 = -1.0
print("remainder(10, 3):", math.remainder(10, 3))  # 10 / 3 = 3.33 -> n=3 -> 10 -  9 =  1.0

Output:

remainder(12, 7): -2.0
remainder(12, 5):  2.0
remainder(13, 7): -1.0
remainder(10, 3):  1.0

Comparison: math.remainder() vs. math.fmod() vs. % (Modulo) 🔝

Python offers three distinct remainder functions, each following a different integer rounding rule for the quotient n:

Operation Quotient Rule n Sign of Remainder Output Range Zero Divisor Error
math.remainder(x, y) Nearest integer (round to even) Can be positive or negative [−|y|/2, |y|/2] ValueError
math.fmod(x, y) Truncated towards zero Same sign as x (-|y|, |y|) ValueError
x % y (Modulo) Floor towards -∞ Same sign as y [0, y) if y > 0 ZeroDivisionError

Comparing outcomes across mixed-sign numbers:

import math

test_pairs = [(12, 7), (7, 4), (-12, 7), (12, -7), (-12, -7)]

print(f"{'Pair (x, y)':>14} | {'math.remainder':>15} | {'math.fmod':>10} | {'x % y':>6}")
print("-" * 52)

for x, y in test_pairs:
    rem = math.remainder(x, y)
    fmod_val = math.fmod(x, y)
    mod_op = x % y
    print(f"{str((x, y)):>14} | {rem:15.1f} | {fmod_val:10.1f} | {mod_op:6.1f}")

Output:

   Pair (x, y) |  math.remainder |  math.fmod |  x % y
----------------------------------------------------
       (12, 7) |            -2.0 |        5.0 |    5.0
        (7, 4) |            -1.0 |        3.0 |    3.0
      (-12, 7) |             2.0 |       -5.0 |    2.0
      (12, -7) |            -2.0 |        5.0 |   -2.0
     (-12, -7) |             2.0 |       -5.0 |   -5.0

Halfway Cases: Round-Half-to-Even Rule 🔝

When x / y lands exactly on a .5 boundary halfway between two integers, math.remainder() breaks the tie by choosing the nearest even integer:

import math

# 1.5 / 1.0 = 1.5 -> nearest integers are 1 and 2 -> choose even 2 -> 1.5 - 2*1 = -0.5
print("remainder(1.5, 1.0):", math.remainder(1.5, 1.0))  # -0.5

# 2.5 / 1.0 = 2.5 -> nearest integers are 2 and 3 -> choose even 2 -> 2.5 - 2*1 =  0.5
print("remainder(2.5, 1.0):", math.remainder(2.5, 1.0))  #  0.5

# 3.5 / 1.0 = 3.5 -> nearest integers are 3 and 4 -> choose even 4 -> 3.5 - 4*1 = -0.5
print("remainder(3.5, 1.0):", math.remainder(3.5, 1.0))  # -0.5

Output:

remainder(1.5, 1.0): -0.5
remainder(2.5, 1.0):  0.5
remainder(3.5, 1.0): -0.5

Angle Normalization: Degrees [−180°, 180°] and Radians 🔝

The most important real-world application of math.remainder() is angle wrapping. In robotics, flight avionics, and 3D game engines, angular bearings must be normalized so that deviations are represented within a symmetric range about zero:

  • Degrees: math.remainder(angle, 360) normalizes any heading into [−180°, 180°].
  • Radians: math.remainder(angle, 2 * math.pi) normalizes any angle into [−π, π].
import math

angles_deg = [370, 350, 190, -200, 725]

print(f"{'Original':>10} | {'Normalized [-180, 180]':>24}")
print("-" * 38)

for a in angles_deg:
    norm = math.remainder(a, 360)
    print(f"{a:9d}° | {norm:22.1f}°")

Output:

  Original |   Normalized [-180, 180]
--------------------------------------
      370° |                   10.0°
      350° |                  -10.0°
      190° |                 -170.0°
     -200° |                  160.0°
      725° |                    5.0°

Special Values & Exception Handling 🔝

Examine how math.remainder() handles division by zero and IEEE 754 non-finite values:

import math

# 1. Zero divisor raises ValueError (unlike modulo which raises ZeroDivisionError)
try:
    math.remainder(10.0, 0.0)
except ValueError as err:
    print("remainder(10, 0) ValueError:", err)

# 2. Infinite dividend raises ValueError
try:
    math.remainder(float('inf'), 5.0)
except ValueError as err:
    print("remainder(inf, 5) ValueError:", err)

# 3. Finite dividend with infinite divisor returns dividend
print("remainder(7.0, inf):          ", math.remainder(7.0, float('inf')))  # 7.0

Output:

remainder(10, 0) ValueError: math domain error
remainder(inf, 5) ValueError: math domain error
remainder(7.0, inf):           7.0

Hands-on Exercise: Robotics Autonomous Heading Navigator with Assertions 🔝

In autonomous mobile robotics and self-driving vehicles, an onboard navigator must compute the shortest rotational steering delta (Δθ) to align the robot's current heading with a waypoint bearing. Using math.remainder() ensures the robot always turns via the shortest arc without glitching across the 0°/360° boundary:

Python Exercise: Shortest Steering Turn Angle Navigator
import math

def calculate_steering_turn(current_heading, target_heading):
    """
    Computes the shortest angular turn in degrees from current_heading to target_heading.
    Returns:
      - Positive float: turn right (clockwise)
      - Negative float: turn left (counter-clockwise)
      - Float strictly in range [-180.0, 180.0]
    """
    if not (isinstance(current_heading, (int, float)) and isinstance(target_heading, (int, float))):
        raise TypeError("Headings must be numeric values.")
        
    raw_delta = target_heading - current_heading
    turn_angle = math.remainder(raw_delta, 360.0)
    return round(turn_angle, 2)

# Unit Assertions
# 1. Simple clockwise turn: 45° -> 90° requires +45°
assert calculate_steering_turn(45, 90) == 45.0

# 2. Simple counter-clockwise turn: 90° -> 45° requires -45°
assert calculate_steering_turn(90, 45) == -45.0

# 3. Crossing the North meridian (350° to 10°): shortest turn is +20° right (not -340°)
assert calculate_steering_turn(350, 10) == 20.0

# 4. Crossing the North meridian counter-clockwise (10° to 350°): shortest turn is -20°
assert calculate_steering_turn(10, 350) == -20.0

# 5. Exactly opposite direction (180°): bank tie-breaking to even yields 180.0
assert calculate_steering_turn(0, 180) == 180.0

print("Steering turn from 355° to 15°:", calculate_steering_turn(355, 15), "°")
print("All robotics steering navigator assertions passed successfully!")

Practice in Google Colab & GitHub 🔝

Open in Google Colab View on GitHub

Run all math.remainder() examples interactively, contrast precision with math.fmod() and %, test half-to-even tie breaking, and execute robotics heading calculations in Google Colab.




Subscribe to our YouTube Channel here



plus2net.com







Python Video Tutorials
Python SQLite Video Tutorials
Python MySQL Video Tutorials
Python Tkinter Video Tutorials
✖
We use cookies to improve your browsing experience. . Learn more
HTML MySQL PHP JavaScript ASP Photoshop Articles Contact us
© 2000-2026 plus2net.com All rights reserved worldwide Privacy Policy Disclaimer