概要
Python3では、設計上、整数同士の除算でも結果が浮動小数点数として返されることになっています。本記事ではmath
を使ったサンプルコード、実数除算と整数除算、情報落ちなどについて解説します。
除算では割り切れる場合でもfloat型になる
公式ドキュメントでも以下のように記載されています。
除算 (/) は常に浮動小数点数を返します。 // 演算子は 整数除算 を行い、整数値を返します; 剰余は、% で求めます。:
引用元:3.1.1. 数¶
以下ではわかりやすい例もあります。
3 / 3 のように割り切れる場合でも、答えは整数の 1 ではなく、小数点以下が
0
のfloat型になります。
1.0
引用元:整数と実数: ゼロからのPython入門講座
Pythonでは(というか他の言語でも一緒と思われる?)、/
は浮動小数点用の割算で、//
が整数用の割算となっています。これは、整数除算と言い、小数点以下を切り捨てた整数値が返ってきます。
※Python 2では、/
演算子は整数同士の除算であり、整数の割り算の結果も整数になっていたようです...
簡単にいうと、以下の通り。
- 実数除算 = 除算結果に小数部を含む
- 整数除算 = 除算結果から小数部分を切り捨てて整数部のみを取り出す
サンプルコード
以下、 普通の割算(実数除算)を使う場合、整数除算を使って切り捨てにする場合、math.ceil()
を使って切り上げにする場合のサンプルコードと出力結果です。
import math
# 距離(メートル)
distance_meters = 800
# 実数除算を使う場合
minutes = int(distance_meters) / 80
print(f"{distance_meters}メートルの距離を80で割って分数に変換すると、{minutes}分かかります。")
## 出力結果 ##
# 800メートルの距離を80で割って分数に変換すると、10.0分かかります。
# 整数除算を使う場合
minutes = distance_meters // 80
print(f"{distance_meters}メートルの距離を80で割って分数に変換すると、{minutes}分かかります。")
## 出力結果 ##
# 800メートルの距離を80で割って分数に変換すると、10分かかります。
# 距離を80で割り、秒数に変換して切り上げる場合
minutes = math.ceil(distance_meters / 80)
print(f"{distance_meters}メートルの距離を80で割って分数に変換すると、{minutes}分かかります。")
## 出力結果 ##
# 800メートルの距離を80で割って分数に変換すると、10分かかります。
上記の例だと、実数除算の場合のみ10.0
というように小数点以下の0
がついてしまっていることがわかります。
ただし、これだと下二つの区別がつきませんね。
距離を801
にしてみると結果はどうなるでしょうか。
801メートルの距離を80で割って分数に変換すると、10.0125分かかります。
801メートルの距離を80で割って分数に変換すると、10分かかります。
801メートルの距離を80で割って分数に変換すると、11分かかります。
切り捨て、切り上げが行われていることがわかります。
一点注意が必要なのは、math.ceil()
関数は浮動小数点数を使用しているという点。Pythonのfloat
(浮動小数点数)は倍精度を使用し、おおよそ15〜16桁の精度を持っています。なので、精度には制限があります。厳密な計算結果を得たい場合は、float
を経由しない方が良いでしょう。「情報落ち」、というやつですね。
ちなみに、切り捨ての関数はないのか?と思いますが、math.floor()
という関数があります。これを使った結果は以下の通り。
801メートルの距離を80で割って分数に変換すると、10分かかります。
整数除算の結果と同じように、切り捨てられていることがわかりますね。
言わずもがな、round()関数
を使用すれば、数値を偶数丸め(銀行丸め)できます。
# 距離(メートル)
distance_meters = 801
# 偶数丸めで整数値に変換する場合
minutes = round(distance_meters / 80)
print(f"{distance_meters}メートルの距離を80で割って分数に変換すると、{minutes}分かかります。")
## 出力結果 ##
# 801メートルの距離を80で割って分数に変換すると、10分かかります。
この偶数丸めは、四捨五入とは厳密には異なる点が注意です。例えば、0.5
の場合、四捨五入の考え方だと1
になりますが、round関数は最も近い整数値のうち偶数を選ぶことになっているので、結果は0
になります。