Skip to main content

How to Split Floats into Integer and Decimal Parts in Python

This guide explains how to separate a floating-point number in Python into its integer and decimal (fractional) parts. We'll cover the recommended method using math.modf(), discuss alternative approaches using the modulo operator (%) and divmod(), and, crucially, address the limitations of these methods with negative numbers and floating-point representation issues.

The math.modf() function is the most direct and reliable way to split a float into its integer and fractional parts:

import math

my_num = 1.3588
fractional_part, integer_part = math.modf(my_num)

print(fractional_part) # Output: 0.3588 (may have slight representation error)
print(integer_part) # Output: 1.0
print(type(integer_part)) # Output: <class 'float'>
  • The math.modf() method returns a tuple of two floats, the fractional and the integer part.
  • math.modf() correctly handles both positive and negative numbers, returning parts with the same sign as the input:
import math
my_num = -1.3588
fractional_part, integer_part = math.modf(my_num)
print(fractional_part) # Output: -0.3588000000000001 (may vary slightly)
print(integer_part) # Output: -1.0
note

math.modf() returns the integer part as a float. If you need a true integer, convert it using int(integer_part).

Using the Modulo Operator (%) and Floor Division (//)

You can use the modulo operator (%) and floor division (//) to separate the parts, but this method has limitations with negative numbers, and is less readable:

my_num = 1.3588

dec = my_num % 1
print(dec) # Output: 0.3588 (correct for positive numbers)

integer = my_num // 1 # This returns a float
print(integer) # Output: 1.0

my_num = -1.3588
dec = my_num % 1 # Returns the REMINDER
print(dec) # Output: 0.6412 (NOT the fractional part for negative numbers)

integer = my_num // 1
print(integer) # Output: -2.0 (integer part rounded down)
  • Positive Numbers: my_num % 1 correctly isolates the fractional part. my_num // 1 performs floor division, giving the integer part (as a float).
  • Negative Numbers: my_num % 1 returns the remainder after division by 1, which is not the same as the fractional part for negative numbers. my_num // 1 performs floor division and rounds down (towards negative infinity), so -1.3588 becomes -2.0.
note
  • You can not directly and reliably use the remainder operator % to extract decimal values when working with negative numbers.
  • Avoid this method for general use. math.modf() is clearer and handles negative numbers correctly.

Using divmod()

The divmod() function returns the quotient and remainder of a division. Like the modulo operator method, it has limitations with negative numbers, and is less readable.

my_num = 1.3588
integer_part, fractional_part = divmod(my_num, 1)

print(integer_part) # Output: 1.0
print(fractional_part) # Output: 0.3588 (correct for positive)

my_num = -1.3588
integer_part, fractional_part = divmod(my_num, 1)
print(integer_part) # Output: -2.0 (Rounded down)
print(fractional_part) # Output: 0.6412 (NOT the fractional part)
  • divmod(my_num, 1): Returns a tuple: (quotient, remainder).
  • Positive Numbers: The quotient is equivalent to the integer part (after truncation), and the remainder is the fractional part.
  • Negative Numbers: The quotient is rounded down (towards negative infinity), and the remainder is not the fractional part you'd expect.
note
  • The return type for divmod will always match the input types, meaning that a float input will return a float.
  • Avoid divmod() for this task. math.modf() is clearer and handles negative numbers correctly.

Limitations of Float Representation

It's crucial to understand that floating-point numbers are not perfectly precise due to their binary representation. This can lead to small representation errors:

import math

my_num = 1.3588
fractional_part, integer_part = math.modf(my_num)
print(fractional_part) # Output: 0.3588000000000001 (may vary slightly)

You might see a value like 0.3588000000000001 instead of exactly 0.3588. This is not a bug in Python; it's a fundamental limitation of how floating-point numbers are stored.

Solutions:

  • Decimal: If you need exact decimal representation (e.g., for financial calculations), use the decimal.Decimal class instead of float.
  • Rounding: For display purposes, round the fractional part to a specific number of decimal places using round() or f-string formatting:
    print(f"{fractional_part:.4f}")  # Format to 4 decimal places. Output: 0.3588

Converting a Float to an Integer

If you need to completely remove the fractional part, you can convert the number to an integer by:

  • Using truncation towards zero with math.trunc() or int():
    import math
    result_1 = math.trunc(3.999)
    print(result_1) # Output: 3
    result_2 = int(-3.99)
    print(result_2) # Output: -3
  • Using math.floor() to round down towards negative infinity.
    import math
    result_1 = math.floor(3.999)
    print(result_1) # Output: 3
    result_2 = math.floor(-3.99)
    print(result_2) # Output: -4
  • You can also use rounding by using the round() method:
    result_1 = round(3.999)
    print(result_1) # Output: 4
    result_2 = round(-3.99)
    print(result_2) # Output: -4
  • You can also round up using the math.ceil() method:
    import math
    result_1 = math.ceil(3.999)
    print(result_1) # Output: 4
    result_2 = math.ceil(-3.99)
    print(result_2) # Output: -3

Conclusion

The math.modf() function is the recommended way to split a float into its integer and fractional parts in Python.

  • It handles both positive and negative numbers correctly and is more readable than alternative methods.
  • Be aware of floating-point representation limitations and use Decimal or rounding as needed for precise calculations or display.
  • Using modulo (%) or divmod() are not appropriate solutions to this specific problem.