[ Сборник задач ]
Тема 2.Числа с плавающей
точкой

[ Сборник задач ]
Тема 2.Числа с плавающей
точкой

Python Workbook Cover
Тип данных: float
Контент: Вопросы (8шт) + задачи (6шт)

Оглавление

1
Введение
Рассмотрим особенности работы с числами с плавающей точкой: выделим основные проблемные места и моменты, на которые следует обратить внимание.
Перейти
2
Вопросы и ответы
8 вопросов по теме "Числа с плавающей точкой" + ответы
Перейти
3
Условия задач
6 задач по теме двух уровней сложности: Базовый и *Продвинутый
Перейти
4
Решения задач
Приводим код решений указанных выше задач
Перейти
1
One

Введение

Операции над числами с плавающей точкой могут вызывать ошибки и давать неожиданные результаты. Работа с типом float требует повышенного внимания.

Также отображение таких чисел конечно, несмотря на то что в математике имеются иррациональные числа (например, Пи, корень квадратный из двух).
При изучении темы следует обратить внимание на:

  1. Структуру числа с плавающей точкой (какие его части сохраняются в памяти и сколько бит занимает каждая);
  2. Конструктор типа float;
  3. Способы преобразования в целые числа (trunc, floor, ceiling, round);
  4. Правила округления.

Если вы можете избежать применения чисел с плавающей точкой, этим стоит воспользоваться, так как они могут давать при вычислениях ложные результаты с точки зрения математики. При необходимости точного итога на практике используют встроенный модуль decimal (десятичные числа) или fractions (дроби).

Читайте также

2
Two

Вопросы по теме "Числа с плавающей точкой"

1. Какой тип данных получится в результате вычисления выражения: 3 + 3.0 + 4?
Сначала вычислим выражение, а потом определим его тип при помощи функции type().

Решение – Интерактивный режим
>>> 3 + 3.0 + 4
10.0
>>> type(10.0)
<class 'float'>


Как видим, получается тип float, т.е. число с плавающей точкой.

2. Из каких трех элементов состоит тип данных float?

Числа типа float состоят из:

– знака (+ или -);
– экспоненты, обозначающей степень десятки (например, е+5);
– значимых чисел (до и после запятой).

-11.03е+5 – типичная запись вещественного числа. Она аналогична варианту -11.03 * 10 ** 5 или -1103000.0.
3. Какой результат дает применение операции int(a) к любому числу «а» с плавающей точкой?
В результате всегда получим целое число. Знак сохраняется, целочисленная часть остается, а вся дробная часть отрезается.

Примеры – Интерактивный режим
>>> int(3.93)
3
>>> type(int(3.93))
<class 'int'>
>>> int(-11.328)
-11
>>> type(int(-11.328))
<class 'int'>



4. Какой самый простой способ получения нуля с плавающей точкой (т.е. числа 0.0)? Использовать можно только функцию float().

Первое, что приходит на ум: передать 0 в качестве аргумента внутрь функции float().

Решение – Интерактивный режим
>>> float(0)
0.0


Однако, все еще проще: если не передавать аргумент, то по умолчанию ставится 0.

Решение – Интерактивный режим
>>> float()
0.0
5. Каким методом можно проверить, является ли заданное вещественное число целым?

С нашей точки зрения 4.0 и 4 – равные числа, и оба являются целыми, так как 0 после точки не несет никакой смысловой нагрузки. В Python эти числа также равны, но первое относится к типу float, а второе – к int.

Для ответа на вопрос можно использовать 2 варианта:

A. Преобразовать число в тип int и сравнить его с самим собой.

Решение – Интерактивный режим
>>> int(4.0) == 4.0
True


Б. Так как в вопросе использовано слово «метод», то логичнее воспользоваться соответствующим методом.

Решение – Интерактивный режим
>>> (4.0).is_integer()
True

6. Какие типы данных можно преобразовать в числа с плавающей точкой?

К вещественным числам можно преобразовать строки и числа:

– целые числа

Решение – Интерактивный режим
>>> float(8)
8.0


– вещественные числа

Решение – Интерактивный режим
>>> float(8.0)
8.0


– булевы значения (т.к. они относятся, в том числе, к типу int)

Решение – Интерактивный режим
>>> float(False)
0.0


– числовые строки

Решение – Интерактивный режим
>>> float('4.6')
4.6


– экземпляры классов Decimal и Fraction

Решение – IDE
from decimal import Decimal
from fractions import Fraction
print(float(Decimal(10.4)))
print(float(Fraction(5, 2)))


Результаты:
10.4
2.5

7*. В чем суть банковского округления в Python (стандарт IEEE 754)?

В языке Python используется так называемое банковское округление (на основании стандарта IEEE 754). Его суть в следующем: округление числа производится в сторону ближайшего значения, а если последняя цифра 5, то в сторону ближайшего четного числа.

Примеры – Интерактивный режим
>>> round(2.3)
2
>>> round(2.8)
3
>>> round(-2.8)
-3
>>> round(2.5)
2
>>> round(3.5)
4

8*. Какой результат дадут выражения int(5.2) и math.trunc(5.2)? Есть ли разница при любых случайных аргументах?
Что функция int(), что метод trunc() из модуля math дают одинаковые результаты. По факту, это аналоги, реализующие следующий механизм: отсекается дробная часть и возвращается целочисленное значение с сохранением знака.

Какие бы аргументы мы сюда не передавали, итог вычисления всегда будет одинаковым.

Решение – IDE
from math import trunc
print(int(5.2))
print(trunc(5.2))
print(int(5.2) == trunc(5.2))

Результаты:
5
5
True

3
Three

Задачи по теме "Числа с плавающей точкой"

4
Two

Решения

Задача 1. Базовый уровень

Условие
Напишите функцию to_float(num), которая преобразует любое число в число с плавающей точкой.
Если в качестве аргумента передан другой тип данных, она возвращает «Невозможно преобразовать».
Необходимо сделать проверку аргумента на принадлежность к типу int или float. Если это так, то осуществляем преобразование. В противном случае возвращаем «Невозможно преобразовать». Важно учесть, что и булевы значения можно преобразовать в тип float.
Решение – IDE
def to_float(num):
    if isinstance(num, (int, float)):
        return float(num)
    return "Невозможно преобразовать"

# Тесты
print(to_float(12))
print(to_float(-1.762))
print(to_float(True))
print(to_float('Не число'))
print(to_float('2.2'))
Результат выполнения
12.0
-1.762
1.0
Невозможно преобразовать
Невозможно преобразовать

Задача 2. Базовый уровень

Условие
Дано 4 числа. 
Нужно написать функцию avg_5(a, b, c, d), которая возвращает среднее арифметическое аргументов и округляет его до 5 знаков после запятой.
Для округления воспользуемся встроенной функцией round(). Осталось сложить числа и разделить их на 4.
Решение - IDE
def avg_5(a, b, c, d):
    return round((a + b + c + d) / 4, 5)

# Тесты
print(avg_5(1, 6, 7, 4))
print(avg_5(1.7, 6.2, 2, 6))
print(avg_5(3, -3.143223442, -4.76, 1.3902))
Результат выполнения
4.5
3.975
-0.87826

Задача 3. Базовый уровень

Условие
Функция mul_to_int(a, b) может принимать целые или вещественные числа. 
Если результат умножения аргументов не имеет значимых чисел после запятой, то она возвращает его в виде целого числа. 
В противном случае – в виде float. 
Результат умножения следует проверить на принадлежность к типу int. Следует учесть и тот факт, что у класса int нет метода is_integer().
Решение – IDE
def mul_to_int(a, b):
    res = a * b
    if float(res).is_integer():
        return int(res)
    return res

# Тесты
print(mul_to_int(2, 4))
print(mul_to_int(2.5, 4))
print(mul_to_int(2.2, 2))
Результат выполнения
8
10
4.4

Задача 4. Базовый уровень

Условие
Дан объем шара X куб. ед. 
Найдите радиус фигуры. 
Воспользуемся формулой объема шара:
V = 4/3 * r ** 3 * pi

Отсюда:
r = ((3 * V / (4 * pi)) ** (1/3))
Решение - Интерактивный режим
>>> from math import pi
>>> (3 * 36 / (4 * pi)) ** (1/3)
2.048352189765887
>>> (3 * 1 / (4 * pi)) ** (1/3)
0.6203504908994001
>>> (3 * 19.32 / (4 * pi)) ** (1/3)
1.6645857441456702

* Задача 5. Продвинутый уровень

Условие
Напишите функцию округления round_standard(num), принимающую число с плавающей точкой и округляющую его до целого числа в соответствии с правилами школьной математики.
При решении задачи важно не упустить знак числа. В общем виде подобного рода задание решается прибавлением к исходному параметру 0.5, чтобы избежать правила банковского округления.
Решение - IDE
def round_standard(num):
    if num >= 0:
        sign = 1
    else:
        sign = -1
    return sign * int((abs(num) + 0.5))

# Тесты
print(round_standard(1.5))
print(round_standard(-2.5))
print(round_standard(1.6))
print(round_standard(5.11))
Результат выполнения
2
-3
2
5

* Задача 6. Продвинутый уровень

Условие
Так как в Python операции с вещественными числами могут давать неожиданные результаты (в частности, 0.1 + 0.2 не будет в точности равняться 0.3), стоит задача с этим как-то справляться. 
Требуется написать функцию eqv(a, b, c), которая принимает 3 числа. 
Числа a и b складываются. 
Затем эта сумма сравнивается с числом “с” с определенной степенью точности. 
Точность равняется 0.01 % от большего из чисел a и b. 
Функция вернет True, если выполняется равенство, иначе False.
Мы уже выяснили, что в Python 0.1 + 0.2 != 0.3, тогда как по правилам математики обе части выражения идентичны. Следовательно, половины нужно сравнивать с неким минимальным отклонением «е», величину которого в условии определили как 0.01 %. Если части отличаются на меньшее значение, нежели «е», то они признаются равными.
Решение - IDE
def eqv(a, b, c):
    res = a + b
    e = 0.01 / 100  # Перевод процентов в долю
    tolerance = e * max(abs(a), abs(b))  # Находим значение отклонения
    return abs(res - c) <= tolerance  # Определяем, меньше ли разница, чем отклонение

# Тесты
print(eqv(0.12, 0.31, 0.43))
print(eqv(0.1, 0.2, 0.3))
print(eqv(0.1, 0.2, 0.4))
print(eqv(-0.1, -0.2, -0.3))
Результат выполнения
True
True
False
True
Есть более продвинутое решение, если использовать встроенный модуль math. Метод isclose() может принимать не только относительную разницу (в долях), но и абсолютную (в некоторых случаях могут потребоваться обе величины).
Решение - IDE
Решение – IDE
def eqv(a, b, c):
    from math import isclose
    return isclose(a + b, c, rel_tol=0.01 / 100, abs_tol=0)

# Тесты
print(eqv(0.12, 0.31, 0.43))
print(eqv(0.1, 0.2, 0.3))
print(eqv(0.1, 0.2, 0.4))
print(eqv(-0.1, -0.2, -0.3))
Результат выполнения
True
True
False
True
Как вам материал?

Читайте также