ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 25.10.2023
Просмотров: 440
Скачиваний: 3
СОДЕРЖАНИЕ
Задание по программированию: Следующее и предыдущее
Примеры использования логических выражений
Вложенный условный оператор и "иначе-если"
Задание по программированию: Какое число больше?
Задание по программированию: Максимум трех чисел
Задание по программированию: Високосный год
Тренировочное задание по программированию: Ход короля
Тренировочное задание по программированию: Квартиры
Задание по программированию: Коровы
Задание по программированию: Упорядочить три числа
Задание по программированию: Сколько совпадает чисел
Тренировочное задание по программированию: Цвет клеток шахматной доски
Тренировочное задание по программированию: Шоколадка
Задание по программированию: Коровы
Задание по программированию: Узник замка Иф
Задание по программированию: Список квадратов
Задание по программированию: Минимальный делитель
Тренировочное задание по программированию: Список степеней двойки
Задание по программированию: Утренняя пробежка
Задание по программированию: Максимум последовательности
Подсчет суммы и оператор continue
Задание по программированию: Сумма квадратов
Задание по программированию: Длина последовательности
Задание по программированию: Сумма последовательности
Задание по программированию: Максимальное число подряд идущих равных
Задание по программированию: Количество четных элементов последовательности
Задание по программированию: Второй максимум
Задание по программированию: Количество элементов, равных максимуму
Как устроены вещественные числа
Основы работы с вещественными числами
Задание по программированию: Округление по российским правилам
Задание по программированию: Проценты
Задание по программированию: Квадратное уравнение - 1
Задание по программированию: Система линейных уравнений - 1
Задание по программированию: Делаем срезы
Задание по программированию: Первое и последнее вхождение
Задание по программированию: Удаление фрагмента
Задание по программированию: Второе вхождение
Задание по программированию: Переставить два слова
Задание по программированию: Количество слов
Задание по программированию: Замена подстроки
Задание по программированию: Удаление символа
Задание по программированию: Минимум 4 чисел
Возврат нескольких значений функцией
Задание по программированию: Принадлежит ли точка квадрату - 1
Задание по программированию: Принадлежит ли точка кругу
Задание по программированию: Минимальный делитель числа
Локальные и глобальные переменные
Задание по программированию: Проверка числа на простоту
Задание по программированию: Возведение в степень
Задание по программированию: Сложение без сложения
Задание по программированию: Быстрое возведение в степень
Задание по программированию: Сократите дробь
Задание по программированию: Сумма последовательности
Задание по программированию: Разворот последовательности
Задание по программированию: Ряд - 1
Задание по программированию: Ряд - 2
Формат ввода
Вводится последовательность целых чисел, оканчивающаяся числом 0 (само число 0 в последовательность не входит, а служит как признак ее окончания).
n = int(input())
max1 = n
count = 1
while n != 0:
n = int(input())
if n != 0:
if n > max1:
max1 = n
count = 1
elif n == max1:
count += 1
print(count)
Как переменные устроены внутри
В языке Питон все переменные являются ссылками на объекты. Каждый объект имеет тип (нам известны int и str) и содержимое, в нашем случае конкретное число или последовательность символов.
Переменные (ссылки) в языке Питон удобно представлять себе как ярлычки на веревочке, которые привязаны к какому-то объекту. Вообще говоря, к одному объекту может быть привязано сколь угодно много ярлыков. Различные переменные с одинаковым значением фактически являются ярлычками, привязанными к одному и тому же объекту.
Типы int и str в Питоне являются неизменяемыми. Любое присваивание в Питоне не может изменить неизменяемый тип, а может только изменить место, на которое указывает ссылка (и, при необходимости, сконструировать новый объект).
Например, команда x = 2, приведет сначала к созданию объекта типа "целое число" со значением 2 в памяти, а затем к созданию переменной x, которая будет являться ссылкой на этот объект.
Если после этого написать y = 2, то новый объект со значением 2 создаваться не будет, а создастся только новая ссылка с именем y, показывающая на тот же самый объект, что и ссылка x.
Если теперь написать строку x = 3, то с объектом со значением 2 ничего не случится, ведь он неизменяемый. Создастся новый объект со значением 3, ссылка x отвяжется от объекта со значением 2 и привяжется к новому объекту 3. При этом к объекту 2 останется привязана ссылка y.
Если изменить и значение переменной y, то у объекта 2 не останется ссылок на него. Поэтому он может быть безболезненно уничтожен при сборке мусора, ведь получить к нему доступ уже невозможно - на него не ссылается ни одна переменная.
Константные значения в программе (например, явно заданные числа в исходном коде программы) также являются ссылками на объекты, содержимое которых совпадает со значением этих констант. Однако эти ссылки не могут быть изменены и не могут участвовать в присваивании с левой стороны от знака =.
Как устроены вещественные числа
В отличие от целых чисел, вещественные числа в языке Питон имеют ограниченную длину.
Подумаем, как хранить десятичную дробь в памяти. Поскольку вещественных чисел бесконечно много (даже больше, чем натуральных), то нам придется ограничить точность. Например, мы можем хранить только несколько первых значащих цифр, не храня незначащие нули. Будем отдельно хранить целое число с первыми значащими цифрами и отдельно хранить степень числа 10, на которую нужно умножить это число.
Например, число 5.972*10**24 (это масса Земли в килограммах) можно сохранить как 5972 (цифры числа, мантисса) и 21 (на какую степень 10 нужно умножить число, экспонента). С помощью такого представления можно хранить вещественные числа любой размерности.
Примерно так и хранятся числа в памяти компьютера, однако вместо десятичной системы используется двоичные. На большинстве аппаратных систем в языке Питон для хранения float используется 64 бита, из которых 1 бит уходит на знак, 52 бита - на мантиссу и 11 бит - на экспоненту. Это не совсем правда, но достаточно неплохо описывает реальность.
52 бита дают около 15-16 десятичных знаков, которые будут храниться точно. 11 бит на экспоненту также накладывает ограничения на размерность хранимых чисел (примерно от -1000 до 1000 степени числа 10).
Любое вещественное число на языке Питон представимо в виде дроби, где в числителе хранится целое число, а в знаменателе находится какая-либо степень двойки. Например, 0.125 представимо как 1/8, а 0.1 как 3602879701896397/36028797018963968. Несложно заметить, что эта дробь не равно 0.1, т. е. хранение числа 0.1 точно в типе float невозможно, как и многих других "красивых" десятичных дробей.
В целом будет полезно представлять себе вещественное число X как отрезок [X - epsilon; X + epsilon]. Как же определить величину epsilon?
Для этого нужно понять, что погрешность не является абсолютной, т. е. одинаковой для всех чисел, а является относительной. Упрощенно, аппаратную погрешность хранения числа X можно оценить как X*2**(-54).
Чаще всего в задачах входные данные имеют определенную точность. Рассмотрим на примере: заданы два числа X и Y с точностью 6 знаков после точки (значит epsilon=5*10**(-7)) и по модулю не превосходящие 10**9. Оценить абсолютную погрешность вычисления X * Y. Рассмотрим худший случай
, когда X и Y равны 10**9 и отклонились на максимально возможное значение epsilon в одну сторону. Тогда результат вычисления будет выглядеть так:
(X + epsilon) * (Y + epsilon) = XY + (X + Y) * epsilon + epsilon**2
Величина epsilon**2 пренебрежимо мала, XY - это правильный ответ, а (X + Y) * epsilon - искомое значение абсолютной погрешности. Подставим числа и получим:
2 * 10**9 * 5 * 10**(-7) = 10**3
Абсолютная погрешность вычисления составила 1000 (одну тысячу). Что довольно неожиданно и грустно.
Таким образом, становится понятно, что нужно аккуратно вычислять значение погрешности для сравнения вещественных чисел.
Основы работы с вещественными числами
Для записи констант или при вводе-выводе может использоваться как привычное представление в виде десятичной дроби, например 123.456, так и "инженерная" запись числа, где мантисса записывается в виде вещественного числа с одной цифрой до точки и некоторым количеством цифр после точки, затем следует буква ''e'' (или ''E'') и экспонента. Число 123.456 в инженерной записи будет выглядеть как 1.23456e2, что означает, что 1.23456 нужно умножить на 10**2. И мантисса и экспонента могут быть отрицательными и записываются в десятичной системе.
Такая запись чисел может применяться при создании вещественных констант, а также при вводе и выводе. Инженерная запись удобна для хранения очень больших или очень маленьких чисел, чтобы не считать количество нулей в начале или конце числа.
Если хочется вывести число не в инженерной записи, а с фиксированным количеством знаков после точки, то следует воспользоваться методом format, который имеет массу возможностей. Нам нужен только вывод фиксированного количества знаков, поэтому воспользуемся готовым рецептом для вывода 25 знаков после десятичной точки у числа 0.1:
x = 0.1
print('{0:.25f}'.format(x))
Вывод такой программы будет выглядеть как 0.1000000000000000055511151, что еще раз подтверждает мысль о том, что число 0.1 невозможно сохранить точно.
Проблемы вещественных чисел
Рассмотрим простой пример:
if 0.1 + 0.2 == 0.3:
print('Yes')
else:
print('No')
Если запустить эту программу
, то можно легко убедиться в том, что 0.1 + 0.2 не равно 0.3. Хотя можно было надеяться, что несмотря на неточное представление, оно окажется одинаково неточным для всех чисел.
Поэтому при использовании вещественных чисел нужно следовать нескольким простым правилам:
1) Если можно обойтись без использования вещественных чисел - нужно это сделать. Вещественные числа проблемные, неточные и медленные.
2) Два вещественных числа равны между собой, если они отличаются не более чем на epsilon. Число X меньше числа Y, если X < Y - epsilon.
Код для сравнения двух чисел, заданных с точностью 6 знаков после точки, выглядит так:
x = float(input())
y = float(input())
epsilon = 10 ** -6
if abs(x - y) < epsilon:
print('Equal')
else:
print('Not equal')
В случае, если над числами совершались какие-то действия, то значения epsilon нужно вычислять как в приведенном в первом видео примере. В учебных задачах это можно сделать не внутри программы, а один раз руками для худшего случая и применять вычисленное значение как константу.
Задача 1
Даны длины сторон треугольника. Вычислите площадь треугольника.
Формат ввода
Вводятся три положительных действительных числа.
Формат вывода
Выведите ответ на задачу.
Задача 2
По данному числу n вычислите сумму (1 / 1²)+(1 / 2²)+(1 / 3²)+...+(1 / n²).
Формат ввода
Вводится целое положительное число.
Формат вывода
Выведите ответ на задачу.
n = int(input())
ns = 1
while n!=1:
nl = 1 / n**2
ns = ns + nl
n -= 1
print(ns)