Bu modül, C standardı tarafından tanımlanan matematiksel fonksiyonlara erişim sağlar.
Bu fonksiyonlar karmaşık sayılarla kullanılamaz; karmaşık sayılar için destek istediğimizde cmath modülünden aynı isimdeki işlevleri kullanabiliriz. Karmaşık sayıları destekleyen ve desteklemeyen fonksiyon ayrımı çoğu kullanıcının bu kadar fazla matematik ile uğraşmamak istemesi.
Math modülü ile yuvarlama: round, floor, ceil ve trunc
Pythonda yerleşik olarak gelen round
fonksiyonuna ilaveten, math modülü floor
, ceil
, ve trunc
fonksiyonlarını içerir.
x = 1.55
y = -1.55
# en yakın tam sayıya yuvarla
round(x) # 2
round(y) # -2
# ikinci argüman ne kadar ondalıklı sayı kullanılacağını söyler (varsayılan 0)
round(x, 1) # 1.6
round(y, 1) # -1.6
# math modülü bir modül olduğuna göre önce import edilmesi gerekir.
# ardından kullanılabilir.
import math
# x'ten küçük en büyük tam sayı
math.floor(x) # 1
math.floor(y) # -2
# x'ten büyük en küçük tam sayı
math.ceil(x) # 2
math.ceil(y) # -1
# x'in ondalık kısmını kaybet
math.trunc(x) # 1, pozitif sayılar için math.floor ile eşdeğer
math.trunc(y) # -1, negatiff sayılar için math.ceil ile eşdeğer
floor
, ceil
, trunc
, ve round
her zaman float
döndürür.
round(1.3) # 1.0
Uyarı!
Tüm float gösterimlerinde olduğu gibi, bazı sayılar tam olarak gösterilemeyebilir. Bu durum beklenmeyen yuvarlama hatalarına neden olur.
round(2.675, 2) # 2.67, 2.68 değil!
Uyarı: floor, trunc, ve negatif sayılarrın integer bölümü
Python (ve C++ ve Java) negatif sayılar için sıfırdan uzaklaşmayı tercih ederler:
>>> math.floor(-1.7)
-2.0
>>> -5 // 2
-3
Math modülü ile kök alma: math.sqrt ve cmath.sqrt
math
modülü kök almaya yarayan math.sqrt()
-fonksiyonunu içerir. Döndürülen sonuç her zaman float
olur::
import math
math.sqrt(9) # 3.0
math.sqrt(11.11) # 3.3331666624997918
math.sqrt(Decimal('6.25')) # 2.5
Eğer sonuç bir kompleks sayı ise math.sqrt()
fonksiyonu bir ValueError
hatası verir:
math.sqrt(-10)
ValueError: math domain error
math.sqrt(x)
işlevi math.pow(x, 0.5)
veya x ** 0.5
ifadelerinden daha hızlıdır. Ancak bu ifadelerin sonuçları aynı doğruluktadır. math modülüne benzer olan cmath
modülü ise kompleks sayılar için de kök alabilir. Sonuçlar a + bi şeklindedir.
import cmath
cmath.sqrt(4) # 2+0j
cmath.sqrt(-4) # 2j
Peki bu j
ne oluyor? j
kök -1 ifadesine eşdeğerdir. Tüm sayılar a + bi formunda yazılabilir, ya da bu örnekte a + bj şeklinde. a
, bu ifadede sayının gerçek kısmını verir; 2+0j
örneğinde 2. Bu sayının imajiner kısmı olmadığı için b
0’a eşit olur. b
imajiner kısmı gösterir; 2j
ifadesindeki 2 gibi. 2j
ifadesinde reel kısım olmadığı için 0 + 2j
şeklinde de yazılabilir.
Math modülü ile trigonometri
Hipotenüs hesaplama
math.hypot(2, 4) # SquareRoot(2**2 + 4**2) ifadesinin kısa hali
# Çıktı: 4.47213595499958
Dereceden radyana, radyandan dereceye dönüştürme
Tüm math
fonksiyonları argüman olarak radyan bekler. Dolayısıyla öncelikle dereceden radyana dönüştürülmeleri gerekir:
math.radians(45) # 45 dereceyi radyana dönüştür
# Çıktı: 0.7853981633974483
Tüm ters-trigonometrik fonksiyonlar radyan sonuç verirler. Dolayısıyla dereceye geri döndürülmeleri gerekebilir.
math.degrees(math.asin(1)) # asin sonucunu dereceye döndür
# Çıktı: 90.0
Sine, cosine, tangent ve ters fonksiyonlar
# Sin ve arc sin
math.sin(math.pi / 2)
# Çıktı: 1.0
math.sin(math.radians(90)) # Sin(90derece)
# Çıktı: 1.0
math.asin(1)
# Çıktı: 1.5707963267948966 # "= pi / 2"
math.asin(1) / math.pi
# Çıktı: 0.5
# Cos ve arc cos:
math.cos(math.pi / 2)
# Çıktı: 6.123233995736766e-17
# Neredeyse 0'a eşit ama tam eşit değil çünkü "pi" kısıtlı bir kesinlikteki float !
math.acos(1)
# Çıktı: 0.0
# Tan and arc tan:
math.tan(math.pi/2)
# Çıktı: 1.633123935319537e+16
# Çok büyük ama tam olarak sonsuz değil çünkü "pi" kısıtlı bir kesinlikteki float !
# Python 3
math.atan(math.inf)
# Çıktı: 1.5707963267948966 # "pi / 2"
math.atan(float('inf'))
# Çıktı: 1.5707963267948966 # "pi / 2"
math.atan
haricinde iki-argüman alan math.atan2
fonksiyonu da bulunur. Bu fonksiyon doğru kuadrantın hesaplanmasını ve sıfıra bölmeden kaynaklanan hataları engeller.
math.atan2(1, 2) # "math.atan(1/2)"'ye eş değer
# Çıktı: 0.4636476090008061 # ≈ 26.57 derece, ilk kuadrant
math.atan2(-1, -2) # "math.atan(-1/-2)" == "math.atan(1/2)" eşit değil
# Çıktı: -2.677945044588987 # ≈ -153.43 derece (veya 206.57 derece), 3. kuadrant
math.atan2(1, 0) # math.atan(1/0) ZeroDivisionError hatası verir
# Çıktı: 1.5707963267948966 # "pi / 2"
Hiperbolik sin, cos ve tan
# Hiperbolik sin
math.sinh(math.pi) # = 11.548739357257746
math.asinh(1) # = 0.8813735870195429
# Hiperbolik cos
math.cosh(math.pi) # = 11.591953275521519
math.acosh(1) # = 0.0
# Hiperbolik tan
math.tanh(math.pi) # = 0.99627207622075
math.atanh(0.5) # = 0.5493061443340549
Math modülü ile logaritma
math.log(x)
x’in doğal logaritmadaki (e tabanında) değerini verir
math.log(math.e) # 1.0
math.log(1) # 0.0
math.log(100) # 4.605170185988092
math.log
1’e yakın sayılarda kesinliğini kaybeder. Bu durum float sayılardaki kısıtlama nedeniyledir. 1’e yakın sayıların logaritmasını daha hassas elde etmek için math.log1p
kullanılır. Bu fonksiyon 1+argüman ifadesinin logaritmasını alır:
math.log(1 + 1e-20) # 0.0
math.log1p(1e-20) # 1e-20
math.log10
10 tabanındaki logaritma için kullanılır:
math.log10(10) # 1.0
İki argüman verildiğinde, ikinci argüman tabanı belirtir. math.log(x, taban)
:
math.log(100, 10) # 2.0
math.log(27, 3) # 3.0
math.log(1, 10) # 0.0
Math modülünde matematik sabitleri
math
modülü yaygın olarak kullanılan iki matematik sabitini içerir
math.pi
– pi sayısımath.e
– e sayısı (doğal logaritmdeki e tabanı)
>>> from math import pi, e
>>> pi
3.141592653589793
>>> e
2.718281828459045
>>>
Python 3.5’ten itibaren sonsuzluk için ve sayı olmayan değerler için de inf ve nan (“not a number”) sabitleri bulunur. Önceki versiyonlardaki float’a string argümanının verildiği syntax hala geçerlidir.
math.inf == float('inf')
# Çıktı: True
-math.inf == float('-inf')
# Çıktı: True
# NaN hiçbir zaman bir şeye eşit olmaz, kendisine bile
math.nan == float('nan')
# Çıktı: False
Infinity ve NaN (not a number)
Python’un tüm versiyonlarında sonsuz ve NaN (“not a number”) ifadelerini aşağıdaki gibi gösterebiliriz:
pos_inf = float('inf') # pozitif sonsuz
neg_inf = float('-inf') # negatif fsonsuz
not_a_num = float('nan') # NaN ("not a number")
Python 3.5 ve sonrasında ayrıca math.inf
ve math.nan
sabitlerini de kullanabiliriz:
pos_inf = math.inf
neg_inf = -math.inf
not_a_num = math.nan
String çıktısı olalrak ise aşağıdaki sonucu alırız
pos_inf, neg_inf, not_a_num
# Çıktı: (inf, -inf, nan)
Pozitif veya negatif sonsuz ifadesini isinf
methodu ile test ederiz:
math.isinf(pos_inf)
# Çıktı: True
math.isinf(neg_inf)
# Çıktı: True
Direkt mukayese ile de pozitif ve negatifi test ederiz:
pos_inf == float('inf') # or == math.inf Python 3.5+
# Çıktı: True
neg_inf == float('-inf') # or == -math.inf Python 3.5+
# Çıktı: True
neg_inf == pos_inf
# Çıktı: False
Python 3.2 ve sonrasında sonlu ifadeleri isfinite
ile kontrol edebiliriz:
math.isfinite(pos_inf)
# Çıktı: False
math.isfinite(0.0)
# Çıktı: True
Karşılaştırma ifadeleri pozitif ve negatif sonsuz için beklenildiği gibi sonuç verir:
import sys
sys.float_info.max
# Çıktı: 1.7976931348623157e+308 (sonuç sisteme bağlıdır)
pos_inf > sys.float_info.max
# Çıktı: True
neg_inf < -sys.float_info.max
# Çıktı: True
Artimetik bir ifade float
ile gösterebileceğimiz değerden daha büyük bir değer döndürürse, sonuç yine sonsuz olur.
pos_inf == sys.float_info.max * 1.0000001
# Çıktı: True
neg_inf == -sys.float_info.max * 1.0000001
# Çıktı: True
Ancak sıfıra bölme sonsuz sonucunu vermez. ZeroDivisionError
hatası üretirr.
try:
x = 1.0 / 0.0
print(x)
except ZeroDivisionError:
print("Sıfıra bölme")
# Çıktı: Sıfıra bölme
Sonsuz üzerindeki aritmetik işlemler sonsuz sonucunu verir, bazen de NaN:
-5.0 * pos_inf == neg_inf
# Çıktı: True
-5.0 * neg_inf == pos_inf
# Çıktı: True
pos_inf * neg_inf == neg_inf
# Çıktı: True
0.0 * pos_inf
# Çıktı: nan
0.0 * neg_inf
# Çıktı: nan
pos_inf / pos_inf
# Çıktı: nan
NaN hiç bir zaman bir şeye eşit olmaz. Kendisine bile. NaN’ı isnan
ile test ederiz:
not_a_num == not_a_num
# Çıktı: False
math.isnan(not_a_num)
Çıktı: True
NaN her zaman “eşit değil” ile kıyas edilir. Büyüktür ve küçüktür ifadeleri ile test edilmez:
not_a_num != 5.0 # ya da herhangi bir sayı
# Çıktı: True
not_a_num > 5.0 veya not_a_num < 5.0 veya not_a_num == 5.0
# Çıktı: False
NaN üzerindeki aritmetik işlemler her zaman NaN verir. -1 ile çarpma işlemi de buna dahildir: “negatitf NaN” değeri bulunmaz.
5.0 * not_a_num
# Çıktı: nan
float('-nan')
# Çıktı: nan
-math.nan
# Çıktı: nan
Eski float
yönteminde gösterilen NaN ve sonsuz ile Python 3.5+’deki math
kütüphanesi sabitleri arasında belirgin bir fark bulunmaz:
math.inf is math.inf, math.nan is math.nan
# Çıktı: (True, True)
float('inf') is float('inf'), float('nan') is float('nan')
Daha hızlı üs almak için Pow
timeit
modülü ile üs almayı kontrol edelim:
> python -m timeit 'for x in xrange(50000): b = x**3'
10 loops, best of 3: 51.2 msec per loop
> python -m timeit 'from math import pow' 'for x in xrange(50000): b = pow(x,3)'
100 loops, best of 3: 9.15 msec per loop
Yerleşik **
operatorü çoğunlukla daha kolay kullanılır ancak performans söz konusu olduğunda math.pow daha değerlidir. Bununla birlikte pow’un float döndürdüğünü unutmamak gerekir; argüman bir tam sayı olsa bile:
> from math import pow
> pow(5,5)
3125.0
İşaretlerin kopyalanması
Python 2.6 ve sonrasında, math.copysign(x, y)
metodu x
‘i y
‘nin işareti ile verir. Döndürülen değer her zaman float
olur.
math.copysign(-2, 3) # 2.0
math.copysign(3, -3) # -3.0
math.copysign(4, 14.2) # 4.0
math.copysign(1, -0.0) # -1.0, işaretli sıfır değerini destekleyen sistemlerde
İmajiner sayılar
Imajiner sayılar Python’da “j” veya “J” ile gösterilir
1j # kök -1'e eşdeğer.
1j * 1j # = (-1+0j)
Kompleks sayılar ve cmath modülü
cmath
modülü math
modülüne benzerdir. Ancak kompleks sayılar için tanımlanmış fonksiyonlar barındırır.
Öncelikle, kompleks sayılar Python dilinde tanımlı nümerik ifadelerdir, harici bir kütüphane ile gelmez. Dolayısıyla sıradan aritmetik işlemler için cmath’i import etmemiz gerekmez.
Unutmayın: j
(veya J
) kullanıyoruz, i
değil.
z = 2 + 1j
1j
ifadesini kullanırız. Çünkü j
nümerik bir gösterimden ziyade başka bir değişken ismi de olabilir.
1j * 1j
Çıktı: (-1+0j)
1j ** 1j
# Çıktı: (0.20787957635076193+0j) # "i üzeri i" == math.e ** -(math.pi/2)
real
kısım ve imag
(imajiner) kısma ilaveten kompleks konjüge
değeri de bulunur:
# real ve imajiner kısımlar float
z.real, z.imag
# Çıktı: (1.0, 3.0)
z.conjugate()
# Çıktı: (1-3j) # z.conjugate() == z.real - z.imag * 1j
abs
ve complex
yerleşik fonksiyonları da aynı şekilde dilin bir parçasıdır. Dolayısıyla herhangi bir import gerektirmezler:
abs(1 + 1j)
# Çıktı: 1.4142135623730951 # kök 2
complex(1)
# Çıktı: (1+0j)
complex(imag=1)
# Çıktı: (1j)
complex(1, 1)
# Çıktı: (1+1j)
complex
fonksiyonu argüman olarak bir string alabilir, ancak string boşluk içeremez:
complex('1+1j')
# Çıktı: (1+1j)
complex('1 + 1j')
# Exception: ValueError: complex() arg is a malformed string
Ancak çoğu fonksiyon için modülü import etmemiz gerekir, örneğin sqrt
:
import cmath
cmath.sqrt(-1)
# Çıktı: 1j
Doğal olarak sqrt
metodunun davranışı kompleks ve reel sayılar için farklı olacaktır. Kompleks fonksiyonları içermeyen math
için negatif sayıların kökü hata verir:
import math
math.sqrt(-1)
# Exception: ValueError: math domain error
Polar koordinat dönüşümü
cmath.polar(1 + 1j)
# Çıktı: (1.4142135623730951, 0.7853981633974483) # == (sqrt(1 + 1), atan2(1, 1))
abs(1 + 1j), cmath.phase(1 + 1j)
# Çıktı: (1.4142135623730951, 0.7853981633974483) # bir önceki ile aynı
cmath.rect(math.sqrt(2), math.atan(1))
# Çıktı: (1.0000000000000002+1.0000000000000002j)
cmath
modülü math modülünün direkt karşılığı olan fonksiyonları da içerir.
sqrt
metoduna ilaveten, exp
, log
, log10
, trigonometrik ve ters trigonometrik (sin
, cos
, tan
, asin
, acos
, atan
), hiperbolik ve ters hiperbolik (sinh
, cosh
, tanh
, asinh
, acosh
, atanh
). ifadelerin de kompleks versiyonları bulunur. Ancak math.atan2
‘nin kompleks karşılığı yoktur
cmath.log(1+1j)
# Çıktı: (0.34657359027997264+0.7853981633974483j)
cmath.exp(1j * cmath.pi)
# Çıktı: (-1+1.2246467991473532e-16j) # e üzeri i pi == -1, yuvarlama hatası ile
pi
ve e
sabitleri de tanımlıdır. Bu sayıların float
olduğu ve kompleks
olmadığını unutmayın.
type(cmath.pi)
# Çıktı: <class 'float'>
cmath
modülü aynı zamanda isinf
, ve (Python 3.2+) isfinite
ifadelerinin de kompleks formlarını içerir. Bir kompleks sayının reel veya imajiner kısmı sonsuz ise kompleks sayı sonsuz kabul edilir.
cmath.isinf(complex(float('inf'), 0.0))
# Çıktı: True
Benzer şekilde, cmath
modülü isnan
‘ın da kompleks varyantını içerir. Bir kompleks sayının reel veya imajiner kısmı NaN ise kompleks sayı NaN kabul edilir.
cmath.isnan(0.0, float('nan'))
# Çıktı: True
Ancak, cmath
‘de math.inf
ve math.nan
sabitlerinin karşılığı yoktur (Python 3.5+)
cmath.isinf(complex(0.0, math.inf))
# Çıktı: True
cmath.isnan(complex(math.nan, 0.0))
# Çıktı: True
cmath.inf
# Exception: AttributeError: module 'cmath' has no attribute 'inf'
Python 3.5 ve sonrasında, isclose
metodu cmath
ve math
modülleri için tanımlıdır.
z = cmath.rect(*cmath.polar(1+1j))
z
# Çıktı: (1.0000000000000002+1.0000000000000002j)
cmath.isclose(z, 1+1j)
# True