Как хранятся числа в питоне
Перейти к содержимому

Как хранятся числа в питоне

  • автор:

Python для подготовки к олимпиадам, начальный уровень (7-9 классы) (СОШ г. Набережные Челны)

Теоретический материал по теме «Целочисленная арифметика»

Целочисленный тип (int) в Python

Д.П. Кириенко — Программирование на языке Python (школа 179 г. Москвы)

Для хранения целых чисел в Python используется тип int (от англ, integer — целое число). Этот тип позволяет хранить как положительные, так и отрицательные числа, при этом сколь угодно большие (в отличие от большинства языков программирования, где целочисленная переменная обычно занимает лишь несколько байт). Более точно, размер числа ограничен лишь имеющейся памятью.

Для преобразования к целому типу используется функция одноименная с именем типа — int:

s = int(input()) t = int(2.5) 

Для целых чисел определены арифметические операции:

* умножение (пропускать его в выражениях вида 2 * х нельзя);

\// целочисленное деление (дробная часть отбрасывается);

\% остаток от деления;

** возведение в степень.

В арифметических выражениях порядок действий соответствует принятому в математике, для изменения порядка действий используются круглые скобки:

(х — а) * 2 — (а — (1 — с))

Функция abs(x) возвращает модуль (абсолютное значение) числа х.

Присваивания вида х = х + а, х = х // а и т.п. можно писать сокращенно: х += а, х //= а.

Пример считывания одного числа

s = int(input ()) 

Пример считывания двух чисел, вводимых в разных строчках

s = int(input()) t = int(input ()) 

Пример считывания двух чисел, вводимых в одной строке через пробел

s, t = map(int, input().split()) # читаем строку, режем по пробелу # с помощью split, и к каждой части # применяем функцию int 

Числа в Python и методы работы с ними

В Python, как и во всех популярных языках программирования, имеются целые числа (int) и числа с плавающей точкой (float). Но у Python есть и отличительная особенность – комплексные числа (complex).

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

str1 = '1' str2 = '2' num1 = 1 num2 = 2 print(str1+str2) # Выведет '12' print(num1+num2) # Выведет 3

Целые числа (int) в Python

В Python, как и в привычной нам математике, целыми числами являются все числа, которые лишены дробной части, то есть не имеют плавающей точки. Рассмотрим на примере:

num1 = 1 num2 = 2 # Присваиваем переменным целые числа print(num1, num2) # Выведет 1 2

Для упрощения создания больших чисел в Python используется нижнее подчеркивание, а не запятая. Пример:

num = 999_999_999 print(num) # Выведет 999999999 num = 999,999,999 print(num) # Выдаст ошибку

Комьюнити теперь в Телеграм
Подпишитесь и будьте в курсе последних IT-новостей

Числа с плавающей точкой (float)

Для отделения целой части числа в Python используется точка. Рассмотрим создание float-числа на примере:

num1 = 0.1 num2 = 0.22 # Присваиваем переменным целые числа print(num1, num2) # Выведет 0.1 0.22

Комплексные числа (complex)

Как я писал выше, Python поддерживает комплексные числа без установки дополнительных модулей. Рассмотрим создание таких чисел на примере:

# создание и сложение двух комплексных чисел num1 = 1 + 2j num2 = 2 + 4j summa = num1 + num2 print(summa) # Выведет (3+6j)

Проверка типа данных переменной

Для проверки типа данных переменной в Python используется встроенная функция type(). Рассмотрим на примере:

str = ‘1’ int = 1 float = 1.1 com1 = 1 + 2j com2 = 2 + 4j complex = com1 + com2 print(type(str)) # Выведет print(type(int)) # Выведет print(type(float)) # Выведет print(type(complex)) # Выведет

Арифметические действия в Python

Сложение делается с помощью оператора “+”. Пример:

a = 1 + 1 print(a) # Выведет 2

С помощью сложения можно преобразовать целое число в число с плавающей точкой. Рассмотрим на примере:

a = 1 + 1.0 print(a) # Выведет 2.0

Вычитание выполняется с помощью оператора “”. Пример:

a = 1 - 1 print(a) # Выведет 0

Умножение делается с помощью оператора “*”:

a = 2 * 2 print(a) # Выведет 4

Возведение в степень выполняется с помощью оператора “**”. Пример:

a = 2**3 print(a) # Выведет 8

Также возведение в степень можно производить с помощью функции pow():

num1 = 2 num2 = 3 print(pow(num1, num2)) # Выведет 8

Деление выполняется с помощью оператора “/”. Пример:

a = 4 / 2 print(a) # Выведет 2

Для получения остатка от деления используется оператор “%”. Пример:

a = 5 % 2 print(a) # Выведет 1

Целочисленное деление выполняется с помощью оператора “//”. Пример:

a = 5 // 2 print(a) # Выведет 2

Округление чисел с плавающей точкой

Для округления float-чисел до ближайшего целого числа используется функция round(). Рассмотрим на примере:

num1 = 1.4 num2 = 1.6 print(round(num1)) # Выведет 1 print(round(num2)) # Выведет 2

Получение модуля числа

Для получения модуля любого числа мы можем использовать функцию abs(). Рассмотрим на примере:

num1 = -2 num2 = 3 print(abs(num1)) # Выведет 2 print(abs(num2)) # Выведет 3

Вывод

Мы разобрали функции для работы с числами в Python и научились ими пользоваться. Надеюсь, эта статья оказалась для вас полезной. Удачи в ваших начинаниях!

Как хранятся числа в питоне

Если вы писали код на Python, то весьма высока вероятность того, что вы, хотя бы в одной из своих программ, пользовались числами. Например, это могли быть целые числа для указания индекса значения в списке, или числа с плавающей точкой, представляющие суммы в некоей валюте.

Но числа в Python — это гораздо больше, чем, собственно, их числовые значения. Поговорим о трёх особенностях чисел в Python, с которыми вы, возможно, не знакомы.

№1: у чисел есть методы

В Python практически всё — это объект. Один из первых объектов, о котором узнаёт тот, кто начинает изучать Python — это str , используемый для представления строк. Возможно, вы сталкивались с использованием методов строк, вроде .lower() , который возвращает новую строку, все символы которой приведены к нижнему регистру:

>>> "HELLO".lower() 'hello'

Числа в Python тоже, как и строки, являются объектами. У них тоже есть методы. Например, целое число можно преобразовать в байтовую строку с помощью метода .to_bytes() :

>>> n = 255 >>> n.to_bytes(length=2, byteorder="big") b'\x00\xff'

Параметр length указывает на количество байтов, которые нужно использовать при составлении байтовой строки, а параметр byteorder определяет порядок байтов. Например, установка параметра byteorder в значение «big» приводит к возврату байтовой строки, в которой старший байт расположен первым, а установка этого параметра в значение «little» приводит к тому, что первым идёт младший байт.

255 — это максимальное значение, которое может принимать 8-битное целое число. Поэтому в нашем случае при вызове метода .to_bytes() можно без проблем воспользоваться параметром length=1 :

>>> n.to_bytes(length=1, byteorder="big") b'\xff'

А вот если записать в n число 256 и вызвать для него . to_bytes() с параметром length=1 , будет выдана ошибка OverflowError :

>>> n = 256 >>> n.to_bytes(length=1, byteorder="big") Traceback (most recent call last): File "", line 1, in OverflowError: int too big to convert

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

>>> int.from_bytes(b'\x06\xc1', byteorder="big") 1729

Методы класса вызывают, используя имя класса, а не его экземпляр. Именно поэтому в предыдущем примере метод .from_bytes() вызывают, обращаясь к int .

Любопытный факт: 1729 — это самое маленькое положительное число, которое можно представить в виде суммы кубов двух положительных чисел двумя способами. Исторический анекдот связывает это число с индийским математиком Сринивасой Рамануджаном, который рассказал о нём своему наставнику Готфри Харолду Харди.

Харди часто навещал Рамануджана, когда тот, умирая, находился в больнице в Патни. Именно в одно из таких посещений произошёл «инцидент» с номером такси. Харди приехал в Патни на такси, воспользовавшись своим излюбленным транспортным средством. Он вошёл в палату, где лежал Рамануджан. Начинать разговор Харди всегда было мучительно трудно, и он произнёс свою первую фразу: «Если не ошибаюсь, то номер такси, на котором я приехал, 1729. Мне кажется, это скучное число». На что Рамануджан тотчас же ответил: «Нет, Харди! О нет! Это очень интересное число. Это самое малое из чисел, представимых в виде суммы двух кубов двумя различными способами».

Один из способов представления числа 1729 в виде суммы двух кубов — это 1 3 + 12 3 . Можете отыскать второй способ?

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

>>> n = 2.0 >>> n.is_integer() True >>> n = 3.14 >>> n.is_integer() False

Вот — интересный метод .as_integer_ratio() . Он, вызванный для числа с плавающей точкой, возвращает кортеж, содержащий числитель и знаменатель дроби, представляющей это число:

>>> n.as_integer_ratio() (1, 2)

Правда, из-за ошибки представления чисел с плавающей точкой, иногда этот метод возвращает неожиданные результаты:

>>> n = 0.1 >>> n.as_integer_ratio() (3602879701896397, 36028797018963968)

Если надо — можно вызывать методы на числовых литералах, заключённых в круглые скобки:

>>> (255).to_bytes(length=1, byteorder="big") b'\xff' >>> (3.14).is_integer() False

Если обойтись без скобок — при попытке вызова метода на целочисленном литерале будет выдана ошибка SyntaxError . А вот при вызове метода числового литерала с плавающей точкой отсутствие скобок, что странно, не приведёт к ошибке:

>>> 255.to_bytes(length=1, byteorder="big") File "", line 1 255.to_bytes(length=1, byteorder="big") ^ SyntaxError: invalid syntax >>> 3.14.is_integer() False

Полный список методов числовых Python-типов можно найти в документации.

№2: числа обладают иерархией

В математике числа обладают естественной иерархией. Например, все натуральные числа являются целыми, а все целые числа — рациональными. Все рациональные числа — это вещественные числа, а все вещественные числа — это комплексные числа.

Похожие рассуждения применимы и к представлению чисел в Python. Здесь «числовая башня» выражается через абстрактные типы, содержащиеся в модуле numbers .

Числовая башня

Все числа в Python являются экземплярами класса Number :

>>> from numbers import Number >>> # Целые числа являются наследниками Number >>> isinstance(1729, Number) True >>> # Числа с плавающей точкой являются наследниками Number >>> isinstance(3.14, Number) True >>> # Комплексные числа являются наследниками Number >>> isinstance(1j, Number) True

Если нужно узнать о том, является ли некое Python-значение числовым, но при этом неважно то, каким именно числовым типом оно представлено, воспользуйтесь конструкцией isinstance(value, Number) .

В Python имеется четыре дополнительных абстрактных типа, иерархия которых, начиная с наиболее общего числового типа, выглядит так:

  1. Класс Complex используется для представления комплексных чисел. Тут имеется один встроенный конкретный тип — complex .
  2. Класс Real — это представление вещественных чисел. Его единственный встроенный конкретный тип — float .
  3. Класс Rational представляет рациональные числа. Его единственным встроенным конкретным типом является Fraction .
  4. Класс Integral применяют для представления целых чисел. В нём имеется два встроенных конкретных типа — int и bool .

Так, погодите, а значения типа bool — это разве числа? Да — числа. Можете это проверить, воспользовавшись REPL:

>>> import numbers >>> # Комплексные числа являются наследниками Complex >>> isinstance(1j, numbers.Complex) True >>> # Комплексные числа не являются наследниками Real >>> isinstance(1j, numbers.Real) False >>> # Числа с плавающей точкой являются наследниками Real >>> isinstance(3.14, numbers.Real) True >>> # Числа с плавающей точкой не являются наследниками Rational >>> isinstance(3.14, numbers.Rational) False >>> # Объекты Fractions - это не наследники Rational >>> from fractions import Fraction >>> isinstance(Fraction(1, 2), numbers.Rational) True >>> # Объекты Fractions - это не наследники Integral >>> isinstance(Fraction(1, 2), numbers.Integral) False >>> # Целые числа - это наследники Integral >>> isinstance(1729, numbers.Integral) True >>> # Логические значения - это наследники Integral >>> isinstance(True, numbers.Integral) True >>> True == 1 True >>> False == 0 True

Всё это, на первый взгляд, выглядит вполне нормально. Правда, порядок несколько нарушает то, что значения типа bool являются числами.

Странность Python: так как тип bool относится к классу Integral (на самом деле он — прямой наследник int ), со значениями True и False можно вытворять довольно необычные вещи.

Например, True можно использовать в роли индекса для того чтобы получить второй элемент итерируемого объекта. А если поделить число на False — будет выдана ошибка ZeroDivisionError .

Попробуйте выполнить «False»[True] и 1 / False в REPL!

Но если присмотреться к числовым типам поближе, окажется, что в иерархии Python-чисел имеется пара своеобразных моментов.

Числа типа Decimal не укладываются в иерархию

Как уже было сказано, в «числовой башне» Python есть 4 конкретных числовых типа, соответствующих четырём абстрактным типам: complex , float , Fraction и int . Но в Python имеется и пятый числовой тип, представленный классом Decimal . Этот тип используется для точного представления десятичных чисел и для преодоления ограничений арифметических операций с плавающей точкой.

Можно предположить, что числа типа Decimal являются наследниками Real , но это, на самом деле, не так:

>>> from decimal import Decimal >>> import numbers >>> isinstance(Decimal("3.14159"), numbers.Real) False

Единственный класс, наследником которого является класс Decimal — это Number :

>>> isinstance(Decimal("3.14159"), numbers.Complex) False >>> isinstance(Decimal("3.14159"), numbers.Rational) False >>> isinstance(Decimal("3.14159"), numbers.Integral) False >>> isinstance(Decimal("3.14159"), numbers.Number) True

Логично то, что класс Decimal не является наследником Integral . В некоторой степени смысл есть и в том, что Decimal не является наследником Rational . Но почему Decimal не является наследником Real или Complex ?

Объекты Decimal обладают всеми методами, определёнными в классе Real, но эти объекты не должны регистрироваться в виде наследников Real, так как Decimal-числа не взаимодействуют с двоичными числами с плавающей точкой (например, результат операции Decimal(‘3.14’) + 2.71828 не определён). Но ожидается, что числа, классы которых являются наследниками абстрактного класса Real, способны взаимодействовать друг с другом (то есть — R1+R2 должно вычисляться в том случае, если числа R1 и R2 представлены типами, являющимися наследниками Real).

Получается, что объяснение странностей сводится к особенностям реализации.

Числа с плавающей точкой — странные создания

А вот числа с плавающей точкой, с другой стороны, реализуют абстрактный базовый класс Real . Они используются для представления вещественных чисел. Но, из-за того, что компьютерная память не является неограниченным ресурсом, числа с плавающей точкой — это лишь конечные аппроксимации вещественных чисел. Это приводит к возможности написания «ненормальных» образцов кода вроде такого:

>>> 0.1 + 0.1 + 0.1 == 0.3 False

Числа с плавающей точкой хранятся в памяти в виде двоичных дробей. Это приводит к появлению некоторых проблем. Например, у дроби 13 нет конечного десятичного представления (после десятичной точки идёт бесконечное множество троек). А у дроби 110 нет конечного представления в виде двоичной дроби.

Другими словами, в компьютере нельзя совершенно точно представить число 0,1 — если только этот компьютер не обладает бесконечной памятью.

Со строго математической точки зрения все числа с плавающей точкой — это рациональные числа, за исключением float(«inf») и float(«nan») . Но программисты используют их в роли аппроксимаций вещественных чисел и воспринимают их, по большей части, как вещественные числа.

Странность Python: float(«nan») — это особое значение с плавающей точкой, представляющее собой «не число». Такие значения часто обозначают как NaN . Но, так как float — это числовой тип, isinstance(float(«nan»), Number) возвращает True .

Получается, что «не числа» — это числа.

В общем, числа с плавающей точкой — странные создания.

№3: набор числовых типов Python можно расширять

Абстрактный числовой базовый тип Python позволяет программисту создавать собственные абстрактные и конкретные числовые типы.

В качестве примера рассмотрим класс ExtendedInteger , который реализует числа в форме a+bp, где a и b — целые числа, а p — простое число (обратите внимание: класс не обеспечивает то, что число p является простым):

import math import numbers class ExtendedInteger(numbers.Real): def init(self, a, b, p = 2) -> None: self.a = a self.b = b self.p = p self._val = a + (b * math.sqrt(p)) def repr(self): return f"(, , )" def str(self): return f" + √" def trunc(self): return int(self._val) def float(self): return float(self._val) def hash(self): return hash(float(self._val)) def floor(self): return math.floor(self._val) def ceil(self): return math.ceil(self._val) def round(self, ndigits=None): return round(self._val, ndigits=ndigits) def abs(self): return abs(self._val) def floordiv(self, other): return self._val // other def rfloordiv(self, other): return other // self._val def truediv(self, other): return self._val / other def rtruediv(self, other): return other / self._val def mod(self, other): return self._val % other def rmod(self, other): return other % self._val def lt(self, other): return self._val < other def le(self, other): return self._val 

Для того чтобы обеспечить правильность реализации интерфейса Real конкретным типом — нужно создать реализации множества методов, в именах которых есть два символа подчёркивания. Ещё нужно поразмыслить о том, как методы вроде .add() и .mul() взаимодействуют с другими типами, являющимися наследниками Real .

Обратите внимание: вышеприведённый пример не создавался в расчёте на его полноту или абсолютную правильность. Его цель — продемонстрировать читателю возможности работы с числами.

При наличии реализации ExtendedInteger можно заниматься следующими вычислениями:

>>> a = ExtendedInteger(1, 2) >>> b = ExtendedInteger(2, 3) >>> a ExtendedInteger(1, 2, 2) >>> # Проверяем то, что a - это наследник Number >>> isinstance(a, numbers.Number) True >>> # Проверяем то, что a - это наследник Real >>> isinstance(a, numbers.Real) True >>> print(a) 1 + 2√2 >>> a * b ExtendedInteger(14, 7, 2) >>> print(a * b) 14 + 7√2 >>> float(a) 3.8284271247461903

Иерархия числовых типов в Python — довольно гибкая структура. Но, конечно, всегда стоит очень внимательно относиться к реализации типов, являющихся наследниками встроенных абстрактных базовых типов Python. Нужно обеспечить их корректную работу друг с другом.

В документации по Python можно найти несколько советов по реализации собственных типов, которые стоит прочесть тому, кто решит заняться созданием собственных числовых типов. Такому человеку ещё полезно будет ознакомиться с реализацией Fraction .

Итоги

Вот — те три особенности Python-чисел, которые мы здесь обсуждали:

  1. У чисел есть методы, как и у практически всех остальных объектов в Python.
  2. Числа обладают иерархией, даже несмотря на то, что их чёткие взаимоотношения несколько портит наличие типов Decimal и float .
  3. Программисты могут создавать собственные числовые типы, которые вписываются в иерархию числовых типов Python.

Может быть, вы узнали из этого материала не только об этих особенностях чисел, но и ещё о чём-нибудь, что вам пригодится.

О, а приходите к нам работать? .

Мы в wunderfund.io занимаемся высокочастотной алготорговлей с 2014 года. Высокочастотная торговля — это непрерывное соревнование лучших программистов и математиков всего мира. Присоединившись к нам, вы станете частью этой увлекательной схватки.

Мы предлагаем интересные и сложные задачи по анализу данных и low latency разработке для увлеченных исследователей и программистов. Гибкий график и никакой бюрократии, решения быстро принимаются и воплощаются в жизнь.

Сейчас мы ищем плюсовиков, питонистов, дата-инженеров и мл-рисерчеров.

Числа с плавающей точкой¶

Десятичные дроби в Python хранятся в формате с плавающей точкой и представлены типом float . Они могут быть записаны несколькими способами:

>>> 1. 1.0 >>> .1 0.1 >>> 4.2 4.2 >>> 4.2e3 # то же, что и 4.2 * 10 ** 3 == 4.2 * 1000 4200.0 >>> 4.2e-3 # то же, что и 4.2 * 10 ** (-3) == 4.2 * 0.001 0.0042 

Конструкция float(x) принимает строку или целое число и возвращает число с плавающей точкой, т.е. объект типа float . Примеры:

>>> float("1.2") 1.2 >>> float(42) 42.0 >>> float("42e3") 42000.0 

Для вывода чисел с плавающей точкой, как и для вывода других объектов, может быть использована функция print :

pi = 3.1415 print(pi) print(f"pi = pi>") 

Также существует способ указать количество выводимых знаков после запятой:

pi = 3.1415 print(f"pi = pi:.3f>") print(f"pi = pi:.4f>") 

При преобразовании чисел с плавающей точкой в целые дробная часть отбрасывается, округления по арифметическим правилам не выполняется:

>>> int(42.9) 42 

Для решения вычислительных задач может быть полезен модуль math из стандартной библиотеки языка Python. Для его использования нужно написать строку import math . Для решения задач нам понадобятся число \(\pi\) и функция извлечения квадратного корня. Примеры их использования:

import math print(f"pi = math.pi>") r = math.sqrt(4) print(f"square root of 4 = r>") 

Задачи¶

  1. Дан диаметр окружности \(d\) . Найти ее длину по формуле \(length = \pi \cdot d\) .
  2. Дано значение температуры \(t\_f\) в градусах Фаренгейта. Определить значение этой же температуры в градусах Цельсия. Температура по Цельсию \(t\_c\) и температура по Фаренгейту \(t\_f\) связаны следующим соотношением:

\[t\_c = (t\_f - 32) \cdot \frac<5>\]
\[ \begin\beginc = \sqrt\\p = a + b + c\end\end \]

© Copyright Revision d00c0df4 .

Built with Sphinx using a theme provided by Read the Docs.
Read the Docs v: latest

Versions latest Downloads html On Read the Docs Project Home Builds Free document hosting provided by Read the Docs.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *