Liczby

https://docs.python.org/3/library/stdtypes.html#numeric-types-int-float-complex

WPROWADZENIE

Python posiada kilka wbudowanych typów liczbowych:

Typy importowane jako moduły:

Po przekroczeniu zakresu int Python 2 automatycznie przeskakuje do typu long.

Nazwa typu jest wykorzystywana przy jawnej konwersji pomiędzy typami. Trzeba pamiętać, że w Pythonie stringi nie są automatycznie konwertowane do liczb. Python automatycznie wykonuje konwersję do typu "szerszego", jeżeli w działaniu występują argumenty różnych typów [int + float = float, float + complex = complex].

Hierarchię typów liczbowych w ramach Abstract Base Classes (ABCs) opisuje PEP 3141.

WYŚWIETLANIE LICZB


>>> 2 * 3.14159      # repr(): jako kod
6.2831799999999998
>>> str(2 * 3.14159)    # str(): w postaci przyjaznej dla użytkownika
'6.28318'
>>> print(2 * 3.14159)     # print korzysta z str()
6.28318
>>> 0.1     # problem reprezentacji dwójkowej, Py2.6-
0.10000000000000001
>>> print(0.1)
0.1
>>> 0.5     # dokładna postać dwójkowa
0.5
>>> 1/0     # wywołujemy wyjątek
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ZeroDivisionError: integer division or modulo by zero
>>> 

WBUDOWANE FUNKCJE MATEMATYCZNE

Funkcje matematyczne działające na liczbach rzeczywistych zawarte są w module math, a działające na liczbach zespolonych w module cmath. Inne moduły matematyczne: random, numpy, scipy, itp.


# Zmienne i wyrażenia różnych typów.

0, 1, -4                      # int
0L, 1L, -3L, 123456789000     # long (Py2)
100_000_000_000               # grouping in integer literals (Py3.6+)

0., .2, -3.45, 2.43e+23       # float
3.14_15_93                    # grouping in floating point literals (Py3.6+)

0j, 2+.3j, 8.9-7J             # complex
z = 5+1j                      # typ complex
z = complex(5, 1)             # użycie konstruktora
z, z.real, z.imag             # część rzeczywista i urojona
z.conjugate()                 # (5-1j), liczba sprzężona do z
abs(z)                        # moduł liczby zespolonej, sqrt((z.real)**2 + (z.imag)**2)

3 ** 2, 1.2 ** 3.5            # potęgowanie, równoważne pow()
pow(3, 2), pow(1.2, 3.5)      # funkcja pow()
pow(2, 10, 5)                 $ (2 ** 10) % 5 = 1024 % 5 = 4

# Konwersja typów (niejawna).

1 + 1.2, 34 / 60.             # int + float = float
1.2 + 3J                      # float + complex = complex

# Konwersja typów (jawna).
# Składnia:
# int(x[, base]), float(x), complex(real[, imag])

int("32"), int(2.345), int(-3.456)
int("111", 2)   # 7; wykorzystanie bazy
int("20", 16), 0x20   # 32; wykorzystanie bazy
float("3.14159"), float(234)
float(1.0 + 2.j)                # TypeError, nie ma jednoznacznej konwersji
str(1234)
long(43)
complex(5), complex(2, 3)                # (5+0J), (2+3J)

# Dzielenie liczb.

5 % 2, 5. % 2., 5 / 2, 5. / 2., 5 // 2, 5. // 2.

# Zaokrąglanie liczb.

round(3.14159, 2)             # 3.14
round(123.456,-1)             # 120.0, ujemna precyzja
round(1.2), round(1.5), round(1.8)      # 1.0, 2.0, 2.0
round(-1.2), round(-1.5), round(-1.8)   # -1.0, -2.0, -2.0
int(1.2+0.5), int(1.5+0.5), int(1.8+0.5)   # 1.0, 2.0, 2.0
int(-1.2+0.5), int(-1.5+0.5), int(-1.8+0.5)   # 0, -1.0, -1.0

# Wartość bezwzględna.

abs(-5), abs(-4.32), abs(1+1j) # 5, 4.32, 1.41421356237

# Liczby całkowite można zapisywać w układzie ósemkowym i szesnastkowym.
23, 027, 0x17, 0X17     # zapis liczby 23
hex(23)   # return string '0x17'

# Pozostałość po ułamkach w liczbach całkowitych.
(4).numerator        # licznik 4
(4).denominator      # mianownik 1

# Funkcja ord() [string --> kod ASCII].
# Funkcja chr() [kod ASCII --> string].

ord("b")   # return 98
chr(99)   # return "c"

# Metody dla liczb float, liczby to obiekty.
# Zamiana na krotkę liczb int, odpowiadającą ułamkowi.

(0.5).as_integer_ratio()      # (1, 2)
(0.6).as_integer_ratio()      # (5404319552844595L, 9007199254740992L)
# Powinno być (3, 5), ale są błędy reprezentacji.

(-.25).as_integer_ratio()     # (-1, 4)

(20.0).is_integer()           # True
(1.5).is_integer()            # False

DZIELENIE LICZB

PEP 238 - Changing the Division Operator.

http://python-history.blogspot.com/2009/03/problem-with-integer-division.html

http://python-history.blogspot.com/2010/08/why-pythons-integer-division-floors.html

Dzielenie liczb w Pythonie przeszło zmianę przy przejściu z Pythona 2 na Python 3. Aby opisać to zagadnienie, trzeba przedstawić trzy pojęcia:

Wydaje się, że głównym powodem wprowadzenia zmiany w działaniu operatora dzielenia było uniknięcie zaskakiwania osób zaczynających naukę programowania, gdzie Python jest ich pierwszym językiem programowania. Python jest językiem o typach dynamicznych i operator dzielenia może działać na dowolnych argumentach przy odpowiednim przeciążenu (overload). Dzielenie klasyczne powoduje sytuacje, które są trudne do zaakceptowania przez początkujących.


>>> 1 == 1.0
True
>>> 2 == 2.0
True
>>> 1 / 2 == 1.0 / 2.0   # dzielenie klasyczne
False

Podsumowanie: domyślne działanie operatorów dzielenia w Pythonie w różnych wersjach [W. J. Chun, Python's "New" Division: Python 2 Versus Python 3, http://www.informit.com/articles/article.aspx?p=1439189 ]:

+--------+---------+----------+----------+
|Operator| 2.1-    | 2.2+     | 3.x      |
+--------+---------+----------+----------+
|  /     |klasyczne|klasyczne |prawdziwe |
+--------+---------+----------+----------+
|  //    | n/a     |bez reszty|bez reszty|
+--------+---------+----------+----------+

Opcje wiersza poleceń związane z dzieleniem (python -Qopcja).

+-----------------------------------------+
| Opcja | Opis                            |
+-----------------------------------------+
| old   |Zawsze dzielenie klasyczne       |
+-----------------------------------------+
| new   |Zawsze dzielenie prawdziwe       |
+-----------------------------------------+
| warn  |Ostrzega przy int/int (long/long)|
+-------+---------------------------------+
|warnall|Ostrzega zawsze przy "/"         |
+-------+---------------------------------+

DZIELENIE KLASYCZNE

Klasyczne dzielenie występuje w Pythonie 2 i innych językach programowania, takich jak C/C++ czy Java. Przy dzieleniu liczb całkowitych część ułamkowa jest odrzucana i zwracana jest liczba całkowita. Przy dzieleniu liczb zmiennoprzecinkowych (float), wynik jest ułamkiem zmiennoprzecinkowym.


>>> 1 / 2        # dzielenie bez reszty
0
>>> -1 / 2        # dzielenie bez reszty
-1
>>> 1.0 / 2.0     # dzielenie prawdziwe
0.5
>>> -1.0 / 2.0     # dzielenie prawdziwe
-0.5
>>>

DZIELENIE PRAWDZIWE

W wyniku dzielenia prawdziwego zawsze powstaje ułamek zmiennoprzecinkowy, niezależnie od typu operandów. Jest to domyślna operacja w Pythonie 3. Od Pythona 2.2 można korzystać z tego rodzaju dzielenia po imporcie division z modułu __future__, albo można uruchomić interpreter z opcją -Qnew.


>>> from __future__ import division  # tylko Python 2.2+
>>> 1 / 2    # zwraca rzeczywisty ułamek
0.5
>>> 1.0 / 2.0   # zwraca rzeczywisty ułamek
0.5
>>>

DZIELENIE BEZ RESZTY

Nowy operator dzielenia bez reszty (//) zawsze odrzuca cząść ułamkową i zaokrągla wynik do najbliższej liczby całkowitej z lewej strony na osi liczbowej. Operator istnieje od Pythona 2.2 i nie wymaga importu. Typ zwracanego wyniku zależy od typu operandów.


>>> 1 // 2   # operandy int, zwraca int
0
>>> 1.0 // 2.0   # operandy float, zwraca float
0.0
>>> -1 // 2
-1
>>> 7 // 2.5
2.0
>>>