カネキン伊藤テック

数値の扱い・計算

math パッケージは組み込みライブラリなので何かをインストールしなくても import できる。

数値リテラル

# 整数
print(0)
print(123)
print(-5)
print(1_000_000)

# 少数(浮動小数点数)
print(0.0)
print(12.3)
print(-1_000.56)
print(123e-4)  #=> 0.0123

# 2進数
print(0b11)  #=> 3
print(-0b111)  #=> -7
print(0b1111_1111)  #=> 255

# 8進数
print(0o12)  #=> 10
print(-0o12)  #=> -163
print(0o11_11)  #=> 585

# 16進数
print(0xff)  #=> 255
print(-0xc3)  #=> -195
print(0xff_ff)  #=> 65535

四則演算(+, -, *, /, //)

割り算の際は /// の違いに注意。前者は浮動小数点数(float型), 後者は整数(int型)を返す。

print(1 + 2)

print(5 - 3)

print(4.2 * 6.5)

print(5 / 2)  #=> 2.5 (float)
print(5 // 2)  #=> 2 (int)

累乗(**, math.pow)

組み込みの演算子 ** と組み込みパッケージmathの関数 math.pow() の2通りのやり方がある。 math.pow() は常に float 型の値を返す

# 2 の 10 乗 (=1024)
n2_10 = 2 ** 10  #=> 1024 (int型)

# math.pow() も使える
import math
math.pow(2, 10)  #=> 1024.0 (float型)

# 少数もつかえる
3.2 ** 5.5  #=> 600.239927187154 (float型)

商と剰余を同時に得る(divmod)

組み込み関数 divmod を使う

quotient, mod = divmod(7, 3)

quotient  #=> 2
mod  #=> 1

少数の切り捨て(floor)

math.floor() で少数部を切り捨てた整数を得る。負の値のときの挙動に注意。

import math

math.floor(3.5)  #=> 3 (型はint)

math.floor(-8.1)  #=> -9

少数の切り上げ(ceil)

math.ceil() で少数部を切り上げた整数を得る。負の値のときの挙動に注意。

import math

math.ceil(1.4)  #=> 2

math.ceil(-5.2)  #=> -5

少数の丸め/四捨五入(round)

floor/ceilと違い組み込み関数 round() で四捨五入ができる。第二引数で n を指定すると少数第n+1位で四捨五入できる。


round(1.4)  #=> 1
round(-1.4)  #=> -1

round(3.5)  #=> 4
round(-3.5)  #=> -4

round(1.234, 2)  #=> 1.23
round(1.56, 1)  #=> 1.6

絶対値を求める(abs)

組み込み関数 abs() で絶対値を求めることができる。

abs(2)  #=> 2
abs(-2)  #=> 2

円周率定数(PI)

組み込みパッケージ math の定数 math.pi を使う。

import math
math.pi  #=> 3.141592653589793

自然対数定数(e)

組み込みパッケージ math の定数 math.e を使う。

import math
math.e  #=> 2.718281828459045

分数(分数)の計算(Fraction)

組み込みパッケージ fractionsFraction クラスを使うことで分数の計算が行える。

# 1000分の1を1000回足すと1になるはずだが実際はならない(浮動小数点数演算の誤差)
sum([1/1000] * 1000)  #=> 1.0000000000000007

# 1000分の1をFractionオブジェクトで表現して1000回足すと1になる
import fractions
fra_sum = sum([fractions.Fraction(1, 1000)] * 1000)  #=> 1 (fractions.Fraction型)
int_fra_sum = int(fra_sum)  #=> 1 (int)
float_fra_sum = float(fra_sum)  #=> 1.0 (float)

# 分数の数字をつくる
fra1 = fractions.Fraction(2, 7)  # 7 分の 2
fra2 = fractions.Fraction(5, 7)  # 7 分の 5

# 計算する
fra3 = fra1 + fra2  #=> 7 分の 7 になるのでつまり 1 (fractions.Fraction(1, 1))

fra4 = fra2 - fra1  #=> 7 分の 3 になるので fractions.Fraction(3, 7)

fra5 = fra1 * 2  #=> 7 分の 4 になるので fractions.Fraction(4, 7)

fra6 = fra1 / 2  #=> 7 分の 1 になるので fractions.Fraction(1, 7)

# 文字列でもFractionオブジェクトを作れる
fra1 == fractions.Fraction("2/7")  #=> True

10進数の正確な演算(Decimal)

組み込みパッケージ deciamlDecimal クラスを使って計算することで浮動小数点数の誤差による影響なく正確な演算が行える。通貨の計算や正確さが必要な科学計算などで役に立つかもしれない。

import decimal

# 普通の数値計算だと浮動小数点数の誤差でゼロにならない
0.125 - 0.1 - 0.02 - 0.005  #=> -6.071532165918825e-18

# 文字列で数字をDecimalのコンストラクタに指定して値を作る
deci1 = decimal.Decimal("0.125")
deci2 = decimal.Decimal("0.1")
deci3 = decimal.Decimal("0.02")
deci4 = decimal.Decimal("0.005")

# 計算するときちんとゼロになる
deci5 = deci1 - deci2 - deci3 - deci4  #=> decimal.Decimal("0.000")
deci5 == decimal.Decimal("0")  #=> True

deci6 = decimal.Decimal("0.1")
deci6 * 10  #=> decimal.Decimal("1.0")
deci6 * 10 == 1  #=> True

# 四則演算
deci1 + deci2  #=> decimal.Decimal("0.225")

deci2 - deci3  #=> decimal.Decimal("0.08")

deci4 * deci2  #=> decimal.Decimal("0.0005")

deci2 / deci2  #=> decimal.Decimal("1")

角度をラジアンに変換

math.radians() で角度をラジアンに変換することができる。

import math
print(math.radians(180.0))  #=> 3.141592653589793

ラジアンを角度に変換

math.degrees() でラジアンを角度に変換することができる。

import math
print(math.degrees(math.pi))  #=> 180.0

三角関数(sin, cos, tan, asin, acos, atan, atan2)

math パッケージにあるそれぞれの関数 sin, cos, tan, asin, acos, atan, atan2 を利用する。

import math

# 正弦(サイン): math.sin()
math.sin(math.radians(30.0))  #=> 0.49999999999999994

# 余弦(コサイン): math.cos()
math.cos(math.radians(60.0))  #=> 0.5000000000000001

# 正接(タンジェント): math.tan()
math.tan(math.radians(45.0))  #=> 0.9999999999999999

# 逆正弦(アークサイン): math.asin()
math.degrees( math.asin(1.0 / 2.0) )  #=> 29.999999999999996

# 逆余弦(アークコサイン): math.acos()
math.degrees( math.acos(math.sqrt(3) / 2) )  #=> 30.000000000000004

# 逆正接(アークタンジェント): math.atan()
math.degrees( math.atan( 1 / math.sqrt(3) ) )  #=> 30.000000000000004

# 逆正接(アークタンジェント): math.atan2(y, x) => y/xに対してのatan
math.degrees( math.atan2( 1, math.sqrt(3) ) )  #=> 30.000000000000004

指数関数(exp, pow)

math.exp() で自然対数の底eのN乗を求められる。公式のドキュメントによると math.e ** N より精度が高いらしい。

import math
e2 = math.exp(2)  #=> 7.38905609893065
e2_2 = math.e ** 2  #=> 7.3890560989306495

math.pow(x, y)xy 乗を計算できる。 x ** y と同じ。

import math
value_is_8 = math.pow(2, 3)  #=> 2 の 3 乗なので 8.0

対数(log)

math.log() で対数を求められる。2を底とする math.log2() や10を底とする math.log10() もある。

import math

# 第二引数を省略した場合は底はeになる
math.log(math.e)  #=> 1.0

# 第二引数で底を指定できる
math.log(8, 2)   #=> 3.0

# 2が底になる math.log2()
math.log2(16)  #=> 4.0

# 10が底になる math.log10()
math.log10(100)  #=> 2.0

平方根・ルート(sqrt)

math.sqrt() で平方根を求められる。

import math

math.sqrt(4.0)  #=> 2.0

math.sqrt(9)  #=> 3.0

順列を求める(perm)

math.perm() で順列を求められる。

import math

# 5P2 の順列
math.perm(5, 2)  #=> 20

# 4P3 の順列
math.perm(4, 3)  #=> 24

組み合わせを求める(comb)

math.comb() で組み合わせを求められる。

import math

# 5C2 の組み合わせ
math.comb(5, 2)  #=> 10

# 4C3 の組み合わせ
math.perm(4, 3)  #=> 4

複数の値の合計を求める(sum)

組み込み関数 sum() で簡単にできる。

values1 = [1, 8, 200]
sum(values1)  #=> 209

values2 = (10, 900, 8600)
sum(values2)  #=> 9510

複数の数値から最大の値を選ぶ

組み込み関数 max() で簡単にできる。

# maxの引数に並べたものから最大のものを選ぶ
max(1, 5)  #=> 5
max(10, 20, 30)  #=> 30

# list/tuple/数値を返すイテレータの中から最大のものを選ぶ
numbers = [1, 2, 3]
max(numbers)  #=> 3

複数の数値から最小の値を選ぶ

組み込み関数 min() で簡単にできる。

# minの引数に並べたものから最小のものを選ぶ
min(1, 5)  #=> 1
min(10, 20, 30)  #=> 10

# list/tuple/数値を返すイテレータの中から最小のものを選ぶ
numbers = [1, 2, 3]
min(numbers)  #=> 1

数値を2進数表記の文字列に変換したい

組み込み関数 bin() が使える。またはstr型の format() メソッドで {:b} を指定する。

bin(15)  #=> "0b1111"

# 頭の "0b" を抜きたい場合
bin(15)[2:]  #=> "1111"

"{:b}".format(15)  #=> "1111"
"{:06b}".format(15)  #=> "001111"  6桁に満たない場合はゼロを詰める

2進数表記の文字列を解釈してintの値にしたい

int() の第二引数 base2 を指定する。

int("1111", base=2)  #=> 15

int("1111", 2)  #=> 15

# 頭に "0b" がついていてもちゃんと解釈される
int("0b1111", 2)  #=> 15

数値を8進数表記の文字列に変換したい

組み込み関数 oct() や文字列のフォーマット指定子 %o が使える。

oct(65)  #=> "0o101"

oct(65)[2:]  #=> "101"

"%o" % 65  #=> "101"
"%04o" % 65  #=> "0101"  4桁に満たない場合にゼロを詰める

8進数表記の文字列を解釈してintの値にしたい

int() の第二引数 base8 を指定する。

int("101", base=8)  #=> 65

int("101", 8)  #=> 65

# 頭に "0o" がついていてもok
int("0o101", 8)  #=> 65

数値を16進数表記の文字列に変換したい

組み込み関数 hex() や文字列のフォーマット指定子 %x および %X が使える。str型の format() メソッドでは {:x} (そして {:X )が使える。

hex(255)  #=> "0xff"

hex(255)[2:]  #=> "ff"

"%x" % 255  #=> "ff" 
"%04x" % 255  #=> "00ff"  4桁に満たない場合はゼロを詰める

"%x" % 255  #=> "FF"
"%04X" % 255  #=> "00FF" ゼロ詰め

"{:x}".format(255)  #=> "ff"
"{:X}".format(255)  #=> "FF"
"{:04x}".format(255)  #=> "00ff"  ゼロ詰め
"{:04X}".format(255)  #=> "00FF"  ゼロ詰め

16進数表記の文字列を解釈してintの値にしたい

int() の第二引数 base16 を指定する。

int("ff", base=16)  #=> 255
int("FF", 16)  #=> 255

# 頭に "0x" がついていてもok
int("0xFF", 16)  #=> 255

参考リンク