Python math.trunc(): Truncating Decimals Towards Zero

The math.trunc(x) function truncates a real number x to an int by discarding its entire fractional part. Unlike math.floor() (which rounds down towards -∞) and math.ceil() (which rounds up towards +∞), math.trunc() always rounds strictly towards zero.

Polymorphic Dunder Protocol: Under the hood, math.trunc(x) delegates directly to the x.__trunc__() special method, allowing custom object classes to define their own integer truncation behavior.

Syntax & Parameters 🔝

The math.trunc() function is part of Python's standard math module:

import math

integer_val = math.trunc(x)
Component Type Description
x float, int, or Object Required. Any numeric value or object implementing the __trunc__() method.
Return Value int The integer component of x truncated towards zero.
TypeError Exception Raised when passing types that do not implement __trunc__() (e.g. strings, lists).
OverflowError Exception Raised when attempting to truncate infinity (float('inf')).
ValueError Exception Raised when attempting to truncate Not-a-Number (float('nan')).

Basic Usage & Rounding Towards Zero 🔝

Observe how math.trunc() strips fractional values without performing upward or downward rounding:

import math

# Positive floats: simply strips decimals
print("trunc(3.14): ", math.trunc(3.14))   # Output: 3
print("trunc(3.99): ", math.trunc(3.99))   # Output: 3 (not rounded to 4)

# Negative floats: rounds upward towards zero
print("trunc(-3.14):", math.trunc(-3.14))  # Output: -3
print("trunc(-3.99):", math.trunc(-3.99))  # Output: -3 (not rounded to -4)

# Pure integers and zeros
print("trunc(42):   ", math.trunc(42))     # Output: 42
print("trunc(0.0):  ", math.trunc(0.0))    # Output: 0
print("trunc(-0.0): ", math.trunc(-0.0))   # Output: 0

Output:

trunc(3.14):  3
trunc(3.99):  3
trunc(-3.14): -3
trunc(-3.99): -3
trunc(42):    42
trunc(0.0):   0
trunc(-0.0):  0

The __trunc__() Dunder Protocol for Custom Classes 🔝

In Python's object-oriented architecture, math.trunc(obj) calls obj.__trunc__(). Any user-defined class can implement this magic method to define custom integer conversion:

import math

class FinancialAmount:
    def __init__(self, dollars, cents):
        self.total = dollars + cents / 100.0
        
    def __trunc__(self):
        """Defines custom truncation for math.trunc()"""
        return math.trunc(self.total)

wallet = FinancialAmount(149, 85)  # $149.85
print("Truncated wallet:", math.trunc(wallet))  # Output: 149
print("Built-in int():   ", int(wallet))         # Output: 149 (falls back to __trunc__)

Output:

Truncated wallet: 149
Built-in int():    149

math.trunc() vs. int() vs. math.floor() vs. math.ceil() 🔝

Understanding the precise behavioral distinctions between Python's integer extraction tools is essential, especially when dealing with negative values:

Function 3.7 -3.7 Direction of Rounding String Parsing?
math.trunc(x) 3 -3 Towards zero (discards decimals) No (TypeError)
int(x) 3 -3 Towards zero (discards decimals) Yes (e.g. int("42"))
math.floor(x) 3 -4 Downwards towards -∞ No (TypeError)
math.ceil(x) 4 -3 Upwards towards +∞ No (TypeError)
round(x) 4 -4 To nearest even integer No (TypeError)
math.modf(x)[1] 3.0 -3.0 Towards zero (returns float) No (TypeError)

Key Difference: math.trunc() vs. int()

While int(3.7) and math.trunc(3.7) produce identical numerical output on floats, their design intent differs:

  • int() is a general-purpose type constructor that parses string representations (int("123")).
  • math.trunc() is an explicit mathematical operation that strictly demands a number or object implementing __trunc__(). Calling math.trunc("123") raises a TypeError.

Handling Infinities, NaNs, and Exceptions 🔝

Because infinity and Not-a-Number have no valid integer representation, math.trunc() raises specific exceptions when passed IEEE 754 non-finite floats:

import math

# 1. Truncating infinity raises OverflowError
try:
    math.trunc(float('inf'))
except OverflowError as err:
    print("OverflowError on inf:", err)

# 2. Truncating NaN raises ValueError
try:
    math.trunc(float('nan'))
except ValueError as err:
    print("ValueError on nan:   ", err)

# 3. Truncating non-numeric string raises TypeError
try:
    math.trunc("42.5")
except TypeError as err:
    print("TypeError on string: ", err)

Output:

OverflowError on inf: cannot convert float infinity to integer
ValueError on nan:    cannot convert float NaN to integer
TypeError on string:  type str doesn't define __trunc__ method

Hands-on Exercise: Video SMPTE Timecode Converter with Assertions 🔝

In digital video editing and broadcasting, continuous media playback elapsed time in seconds (e.g. 3665.48 seconds) must be converted into standard SMPTE Timecode: HH:MM:SS:FF (Hours, Minutes, Seconds, Frames).

Using math.trunc() ensures that fractional leftovers are systematically stripped into their respective discrete components without rounding errors altering frame counts:

Python Exercise: Video SMPTE Timecode Formatter
import math

def seconds_to_smpte(total_seconds, fps=30):
    """
    Converts elapsed seconds into SMPTE timecode string: HH:MM:SS:FF.
    Uses math.trunc() to ensure clean, non-rounding component extraction.
    """
    if not isinstance(total_seconds, (int, float)) or total_seconds < 0:
        raise ValueError("Total seconds must be a non-negative number.")
    if not isinstance(fps, int) or fps <= 0:
        raise ValueError("Frames per second (fps) must be a positive integer.")
        
    # 1. Total integer seconds and fractional sub-second
    int_sec = math.trunc(total_seconds)
    sub_sec = total_seconds - int_sec
    
    # 2. Extract hours, minutes, and remaining seconds
    hours = math.trunc(int_sec / 3600)
    rem_sec = int_sec % 3600
    
    minutes = math.trunc(rem_sec / 60)
    seconds = rem_sec % 60
    
    # 3. Calculate discrete frames
    frames = math.trunc(sub_sec * fps)
    
    return f"{hours:02d}:{minutes:02d}:{seconds:02d}:{frames:02d}"

# Unit Assertions
assert seconds_to_smpte(0.0) == "00:00:00:00"
assert seconds_to_smpte(65.5, fps=30) == "00:01:05:15"      # 0.5s = 15 frames
assert seconds_to_smpte(3661.1, fps=30) == "01:01:01:03"    # 1 hr, 1 min, 1 sec, 3 frames
assert seconds_to_smpte(7200.0, fps=24) == "02:00:00:00"

# Error validation
try:
    seconds_to_smpte(-10.0)
    assert False, "Should raise ValueError"
except ValueError:
    pass

sample_playback = 5423.85  # ~1 hr, 30 min, 23 sec
print(f"Playback ({sample_playback}s at 30fps): {seconds_to_smpte(sample_playback, 30)}")
print("All SMPTE timecode assertions passed successfully!")

Practice in Google Colab & GitHub 🔝

Open in Google Colab View on GitHub

Run all math.trunc() examples interactively, test custom classes with the __trunc__() dunder protocol, inspect error exceptions, and execute SMPTE timecode conversions 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