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.
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')). |
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
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
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) |
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.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
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:
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!")
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.
Author & Instructor at plus2net
I write and maintain practical tutorials on Python, PHP, SQL, JavaScript, HTML, jQuery, and web development at plus2net. The tutorials focus on clear explanations, working examples, and code that readers can test and adapt while learning.