abs() / round() / divmod() / pow()
| 対応: | Python 2(2000) |
|---|
数値の絶対値・丸め・除余・べき乗を計算する組み込み関数です。数値計算でよく使う基本的な演算をシンプルに記述できます。
構文
# 絶対値を返す abs(数値) # 数値を指定した桁数に丸める round(数値, 桁数) # 商と余りをタプルで返す divmod(被除数, 除数) # べき乗を計算する pow(底, 指数) pow(底, 指数, 法) # 底^指数 mod 法(高速な剰余べき乗) # ** 演算子でもべき乗を計算できる 底 ** 指数
関数一覧
| 関数 | 概要 |
|---|---|
| abs(数値) | 数値の絶対値を返します。整数・浮動小数点数・複素数に対応しています。 |
| round(数値, 桁数) | 数値を指定した小数点以下の桁数に四捨五入します。桁数を省略すると整数に丸めます。 |
| divmod(a, b) | aをbで割ったときの商と余りをタプル(商, 余り)で返します。 |
| pow(底, 指数) | 底の指数乗を計算します。第3引数に法を指定すると剰余べき乗を高速に計算できます。 |
| 底 ** 指数 | べき乗演算子です。『pow(底, 指数)』と同じ結果になります。 |
サンプルコード
abs_round_divmod.py
# abs() で絶対値を取得
print(abs(-42)) # 『42』と出力される
print(abs(-3.14)) # 『3.14』と出力される
print(abs(3+4j)) # 複素数のノルム『5.0』と出力される
# round() で四捨五入
print(round(3.14159, 2)) # 『3.14』と出力される
print(round(3.14159, 4)) # 『3.1416』と出力される
print(round(2.5)) # 『2』と出力される(銀行丸め)
print(round(3.5)) # 『4』と出力される(銀行丸め)
print(round(1234, -2)) # 『1200』と出力される(100の位で丸め)
# divmod() で商と余りを同時に取得
quotient, remainder = divmod(17, 5)
print(quotient) # 『3』と出力される(17 ÷ 5 = 3 余り 2)
print(remainder) # 『2』と出力される
# 時間の変換に divmod() を活用
total_seconds = 3661
hours, remainder = divmod(total_seconds, 3600)
minutes, seconds = divmod(remainder, 60)
print(f'{hours}時間{minutes}分{seconds}秒') # 『1時間1分1秒』と出力される
# pow() でべき乗を計算
print(pow(2, 10)) # 『1024』と出力される
print(2 ** 10) # 同じく『1024』と出力される
print(pow(2, -1)) # 『0.5』と出力される
# pow() の第3引数で剰余べき乗を計算(暗号処理などで高速)
print(pow(2, 10, 1000)) # 『24』と出力される(2^10 mod 1000)
実行すると次のように出力されます。
python3 abs_round_divmod.py 42 3.14 5.0 3.14 3.1416 2 4 1200 3 2 1時間1分1秒 1024 1024 0.5 24
よくあるミス
よくあるミス1: round(2.5)が3にならない
Pythonの『round()』は銀行丸め(偶数丸め、IEEE 754準拠)を採用しています。ちょうど中間の値(x.5)は偶数方向に丸められるため、一般的な四捨五入とは挙動が異なります。
# NG: round(2.5)が3になると思い込んでいる print(round(0.5)) # 0(偶数丸め) print(round(1.5)) # 2(偶数丸め) print(round(2.5)) # 2(偶数丸め) print(round(3.5)) # 4(偶数丸め) print(round(4.5)) # 4(偶数丸め)
厳密な四捨五入が必要な場合は『decimal』モジュールの『ROUND_HALF_UP』を使います。
from decimal import Decimal, ROUND_HALF_UP
# OK: decimal で厳密な四捨五入を行う
def round_half_up(value, digits=0):
d = Decimal(str(value))
quantize_str = '1' if digits == 0 else '0.' + '0' * digits
return float(d.quantize(Decimal(quantize_str), rounding=ROUND_HALF_UP))
print(round_half_up(0.5)) # 1.0
print(round_half_up(2.5)) # 3.0
print(round_half_up(3.5)) # 4.0
よくあるミス2: divmodの引数順序間違い
『divmod(a, b)』の引数は「被除数, 除数」の順です。逆にすると商と余りが変わります。
total_seconds = 125 # 引数を逆に渡してしまう minutes_ng, seconds_ng = divmod(60, total_seconds) # 逆! print(minutes_ng, seconds_ng) # 0 60(おかしな値)
次のように記述します。
# 被除数(変換したい値), 除数(単位)の順 minutes_ok, seconds_ok = divmod(total_seconds, 60) print(minutes_ok, seconds_ok) # 2 5(正しい)
よくあるミス3: 浮動小数点数のabs()と誤差
浮動小数点数の演算結果に誤差が含まれていても、abs()はその値をそのまま返します。比較には注意が必要です。
result = 0.1 + 0.2 - 0.3 print(result) # 5.551115123125783e-17(0ではない) print(abs(result)) # 5.551115123125783e-17 print(abs(result) < 1e-10) # True(許容誤差の範囲内かチェックする)
実践パターン
金額・距離・時間変換など実務でよく使うパターンです。
# 金額の四捨五入(消費税計算など)
price = 1980
tax_rate = 0.10
tax = price * tax_rate
print(f'税抜: {price}円')
print(f'税額: {round(tax)}円') # 銀行丸め
print(f'税込: {price + round(tax)}円')
# 差の絶対値でスコアの差を求める
scores = {'夜神月': 98, 'L': 97, '弥海砂': 85, '夜神総一郎': 79, 'ニア': 94}
target = scores['夜神月']
for name, score in scores.items():
diff = abs(score - target)
print(f'{name} との差: {diff}点')
# 時間・分・秒への変換
def format_time(total_seconds):
hours, rem = divmod(total_seconds, 3600)
minutes, seconds = divmod(rem, 60)
return f'{hours}時間{minutes}分{seconds}秒'
print(format_time(7384)) # 2時間3分4秒
print(format_time(59)) # 0時間0分59秒
abs_round_divmod_practice.py
python3 abs_round_divmod_practice.py 税抜: 1980円 税額: 198円 税込: 2178円 夜神月 との差: 0点 L との差: 1点 弥海砂 との差: 13点 夜神総一郎 との差: 19点 ニア との差: 4点 2時間3分4秒 0時間0分59秒
概要
『abs()』は負の数を正の数に変換する絶対値関数で、数値の差の大きさを求めるときなどに使います。複素数に対しては実部と虚部のベクトルのノルム(大きさ)を返します。
『round()』はPythonの銀行丸め(偶数丸め)を採用しており、ちょうど中間の値(x.5)は偶数方向に丸められます。例えば『round(2.5)』は『2』、『round(3.5)』は『4』になります。これはPythonのバグではなく、IEEE 754という国際規格に準拠した仕様です。一般的な四捨五入とは挙動が異なるため注意が必要です。厳密な四捨五入が必要な場合は『decimal』モジュールを使う方法があります。
『divmod()』は商と余りを同時に計算するため、時間・分・秒への変換など桁変換処理に便利です。『pow(a, b, c)』の3引数版は大きな数のべき乗の余りを効率よく計算でき、RSAなどの暗号アルゴリズムでも使われています。
平方根・切り上げ・切り捨てなどの数学関数は『math.sqrt() / math.ceil() / math.floor()』を参照できます。
記事の間違いや著作権の侵害等ございましたらお手数ですがこちらまでご連絡頂ければ幸いです。