Получение целочисленной части числа в Python (truncation)

Раздел: Математика -> Округление

Способы получения целой части числа

Наиболее эффективное решение: функция int()

Функция int() для чисел с плавающей точкой возвращает целое число путем отбрасывания дробной части. Это так называемое усечение (truncation) к нулю. Для положительных чисел результат совпадает с floor, для отрицательных с ceil (так как отбрасывание отрицательной части приближает к нулю).


# Положительное число
a = 5.99
print(int(a))  # 5

Python целая часть числа (целая часть числа в python)

5

Python округление в большую (округление числа в большую сторону в python)


# Отрицательное число
b = -5.99
print(int(b))  # -5
-5

Функция int() работает быстро, так как реализована на C. Она также подходит для строк, но здесь рассматривается работа с числами.

Как получить целую часть с помощью math.trunc()?

Модуль math предоставляет функцию trunc(), которая делает то же самое, что и int(): отбрасывает дробную часть. Разница в том, что math.trunc() может быть переопределена для пользовательских типов, но для стандартных чисел она идентична int().


import math
print(math.trunc(5.99))   # 5
print(math.trunc(-5.99))  # -5
5
-5

Когда стоит отдать предпочтение math.trunc?

Если код использует множество функций из math, применение trunc повышает читаемость. Однако int() короче и не требует импорта.

Как оператор // связан с целой частью числа?

Оператор целочисленного деления // возвращает результат деления, округленный вниз (floor). Для положительных чисел это эквивалентно отбрасыванию дробной части. Но для отрицательных чисел // дает число, меньшее или равное точному частному, что отличается от усечения.


print(7 // 2)   # 3
print(-7 // 2)  # -4
print(int(-7/2)) # -3
3
-4
-3

В каких случаях // подходит для получения целой части?

Если требуется целая часть от деления в математическом смысле (округление вниз), // является правильным выбором. Например, при вычислении индексов или делении массивов.

Почему round() не подходит для получения целой части?

Функция round(x) округляет число до ближайшего целого, а при равной удаленности до четного. Это не отбрасывание дробной части.


print(round(3.5))   # 4
print(int(3.5))     # 3
print(round(2.5))   # 2
print(int(2.5))     # 2
4
3
2
2

Для получения целой части round() не используется.

Как получить целую часть через разность с дробной частью (math.modf)?

Функция math.modf разбивает число на целую и дробную части, возвращая кортеж (дробная, целая).


import math
frac, whole = math.modf(5.99)
print(whole)  # 5.0, но float
print(int(whole))  # 5
5.0
5

Этот способ менее удобен, так как целая часть возвращается как float.

Возможно ли получение целой части через строковое представление?

Можно преобразовать число в строку, разделить по точке и взять первую часть. Однако это неэффективно и работает только для положительных чисел (для отрицательных нужно учитывать знак).


x = 5.99
str_x = str(x)
int_part = int(str_x.split('.')[0])
print(int_part)  # 5
5

Такой метод не рекомендуется для серьезных вычислений.

Как работают math.floor() и math.ceil() для отрицательных чисел?

Для полноты стоит упомянуть, что floor() возвращает наибольшее целое, не превышающее число, а ceil() наименьшее целое, не меньшее числа. Для положительных чисел floor() совпадает с int(), для отрицательных отличается.


import math
print(math.floor(-3.14))  # -4
print(math.ceil(-3.14))   # -3
print(int(-3.14))         # -3
-4
-3
-3

Эти функции не дают целую часть числа в смысле truncation.

Типичные ошибки и проблемы

1. Использование // для отбрасывания дробной части отрицательных чисел приводит к неожиданному результату. Ошибка возникает, если программист ожидает от // усечение, а получает округление вниз.


value = -3.14
wrong = value // 1  # даст -4.0
print(wrong)        # -4.0

2. Путаница между int() и round(). При работе с числами, заканчивающимися на .5, round дает ближайшее четное, что может быть не тем, что нужно.

3. Использование math.floor() для отбрасывания дробной части отрицательных чисел. Результат будет на единицу меньше ожидаемого (для -3.14 floor дает -4 вместо -3).

Чтобы избежать этих проблем, необходимо четко определять нужный тип округления. Если требуется отбросить дробную часть (усечение к нулю), используйте int() или math.trunc().

Пример 1: Обработка отрицательных чисел различными методами

Демонстрация отличий int(), math.trunc(), math.floor(), math.ceil() и // для отрицательных чисел.

Пример

import math
nums = [3.14, -3.14, 5.99, -5.99]
for n in nums:
    print(f'{n:>7} -> int: {int(n):2}  trunc: {math.trunc(n):2}  floor: {math.floor(n):2}  ceil: {math.ceil(n):2}  //1: {n//1:5.1f}')
  3.14 -> int:  3  trunc:  3  floor:  3  ceil:  4  //1:  3.0
 -3.14 -> int: -3  trunc: -3  floor: -4  ceil: -3  //1: -4.0
  5.99 -> int:  5  trunc:  5  floor:  5  ceil:  6  //1:  5.0
 -5.99 -> int: -5  trunc: -5  floor: -6  ceil: -5  //1: -6.0

Пример 2: Получение целой части для элементов списка с помощью map

Применение int() ко всем элементам списка чисел с плавающей точкой.

Пример

values = [1.1, 2.7, 3.4, -4.9, -5.0]
int_parts = list(map(int, values))
print(int_parts)
[1, 2, 3, -4, -5]

Пример 3: Сравнение производительности int() и math.trunc()

Использование timeit для оценки скорости.

Пример

import math, timeit
setup = 'import math; x = 3.14159'
t_int = timeit.timeit('int(x)', setup, number=1000000)
t_trunc = timeit.timeit('math.trunc(x)', setup, number=1000000)
print(f'int: {t_int:.3f} sec')
print(f'trunc: {t_trunc:.3f} sec')
int: 0.134 sec
trunc: 0.142 sec

В данном тесте int() немного быстрее, но разница незначительна.

Пример 4: Использование Decimal для точного отбрасывания дробной части

Модуль decimal позволяет контролировать точность и способ округления. Для усечения (truncation) используется метод quantize с округлением ROUND_DOWN.

Пример

from decimal import Decimal, ROUND_DOWN
x = Decimal('3.1415926535')
truncated = x.quantize(Decimal('1'), rounding=ROUND_DOWN)
print(truncated)  # 3
3

Этот способ полезен, когда важна точность представления (например, финансовые расчеты).

Пример 5: Получение целой части от деления с остатком (divmod)

Функция divmod возвращает пару (частное, остаток). Частное является целой частью от деления с округлением вниз.

Пример

quotient, remainder = divmod(17, 3)
print(quotient, remainder)  # 5 2
# Для отрицательных:
quot2, rem2 = divmod(-17, 3)
print(quot2, rem2)  # -6 1 (так как floor division)
5 2
-6 1

divmod часто используется в алгоритмах, где нужна целая часть частного и остаток одновременно.

Пример 6: Использование NumPy для массивов чисел

Библиотека NumPy предоставляет функцию np.trunc(), которая поэлементно отбрасывает дробную часть.

Пример

import numpy as np
arr = np.array([1.5, -2.7, 3.0, -4.1])
trunc_arr = np.trunc(arr)
print(trunc_arr)
[ 1. -2.  3. -4.]

Функция np.trunc эквивалентна int() для каждого элемента, но возвращает массив с плавающей точкой. Для получения целочисленного массива используйте np.trunc(arr).astype(int).

Целая часть числа в Python - comments

En
Python целая часть числа (python)