天井関数
天井関数 (ceiling function) は、ある実数 $x$ に対して $x$ 以上の最大の整数を返す関数です。$\lceil x \rceil$ あるいは $\mathrm{ceil}(x)$ の記号で表されます。
Python の math.ceil(x) を使って、天井関数の戻り値を確認してみましょう。
# PYTHON_CEILING_FUNCTION # In[1] import math # 天井関数の計算例 a = math.ceil(5) b = math.ceil(3.14) c = math.ceil(-3.14) print("ceil(5):", x) print("ceil(3.14):", x) print("ceil(-3.14):", x) # ceil(5): 5 # ceil(3.14): -3 # ceil(-3.14): -3
NumPy にはユニバーサルな天井関数 numpy.ceil() が用意されています。numpy.ceil() を使って、天井関数のグラフをプロットしてみましょう。
# In[2] import numpy as np import matplotlib.pyplot as plt # データを作成 xx_1 = np.linspace(-4, 4, 65) xx_2 = np.arange(-4, 5) yy_1 = np.ceil(xx_1) yy_2 = np.ceil(xx_2) yy_3 = xx_2 + 1 # 描画エリアの設定 fig, ax = plt.subplots() ax.grid() ax.set_title("Ceiling function", fontsize=16) ax.set_xlabel("x", fontsize=15) ax.set_ylabel("ceil(x)", fontsize=15) ax.set_xlim(-4, 4) ax.set_ylim(-4, 4) # 天井関数をプロット ax.scatter(xx_1, yy_1, marker="_", c="blue") ax.scatter(xx_2, yy_2, c="blue") ax.scatter(xx_2, yy_3, facecolor='None', edgecolors='blue') plt.show()
図を見やすくするために、x が整数値となる座標に ● と ○ を添えてあります。○ はそこで天井関数が値をとらないことを示しています。
math.ceil()
math.ceil(x) は x 以上の最小の整数を返す 天井関数 です。引数が負のときは 0 に近いほうの整数が返ります。
# PYTHON_MATH_CEIL # In[1] import math # ceil(1.5) a = math.ceil(1.5) # ceil(-4.5) b = math.ceil(-4.5) print("ceil(1.5):", a) print("ceil(-4.5):", b) # ceil(1.5): 2 # ceil(-4.5): -4
numpy.ceil()
numpy.ceil() に数値を渡すと、x 以上の最小の整数を返します。引数が負のときは 0 に近いほうの整数を返します。
# NUMPY_CEIL # In[1] import numpy as np x = np.array([10.5, -13.5]) # 天井関数 y = np.ceil(x) print(y) # [11. -13.]
床関数
床関数 (floor function) は、ある実数 $x$ に対して $x$ 以下の最大整数を返します。$\lfloor x \rfloor,\ \mathrm{floor}(x)$ の記号で表します。math モジュールに床関数 math.floor(x) が用意されています。以下に計算例を示します。
# PYTHON_FLOOR_FUNCTION # In[1] import math # floor(10) a = math.floor(10) # floor(e) # eはネイピア数 2.718... b = math.floor(math.e) # floor(-2.5) c = math.floor(-2.5) print("floor(10):", a) print("floor(e):", b) print("floor(-2.5):", c) # floor(10): 10 # floor(e): 2 # floor(-2.5): -3
この実行結果からわかるように、$\lfloor -2.5 \rfloor$ は $-2$ ではなく、$-3$ であることに注意してください。numpy.floor() 関数を使って床関数をプロットしてみます。
# In[2] import numpy as np import matplotlib.pyplot as plt # データを作成 xx_1 = np.linspace(-4, 4, 65) xx_2 = np.arange(-4, 5) yy_1 = np.floor(xx_1) yy_2 = np.floor(xx_2) yy_3 = xx_2 - 1 # 描画エリアの設定 fig, ax = plt.subplots() ax.grid() ax.set_title("Floor function", fontsize=16) ax.set_xlabel("x", fontsize=15) ax.set_ylabel("floor(x)", fontsize=15) ax.set_xlim(-4, 4) ax.set_ylim(-4, 4) # 床関数をプロット ax.scatter(xx_1, yy_1, marker="_", c="blue") ax.scatter(xx_2, yy_2, c="blue") ax.scatter(xx_2, yy_3, facecolor='None', edgecolors='blue') plt.show()
math.floor()
math.floor(x) は x 以上の最大の整数を返す床関数です。引数が負のときは 0 から遠いほうの整数が返ります。
# PYTHON_MATH_FLOOR # In[1] import math # floor(3.8) a = math.floor(3.8) # floor(-7.6) b = math.floor(-7.6) print("floor(3.8):", a) print("floor(-7.6):", b) # floor(3.8): 3 # floor(-7.6): -8
numpy.floor()
numpy.floor() に数値を渡すと、x 以上の最大の整数を返します。引数が負のときは 0 から遠いほうの整数を返します。引数として配列を渡した場合は要素をすべて切り捨てます。
# NUMPY_FLOOR # In[1] import numpy as np x = np.array([10.5, -13.5]) # xの各要素の床関数 y = np.floor(x) print(y) # [10. -14.]
整数部分を取得する関数
math.trunc()
math.trunc() は渡された数値の小数部分を捨てて、整数部分を取得する関数です。戻り値は必ず整数となります。たとえば 10.0 のような浮動小数点数が渡されると整数 10 が返ります。
# PYTHON_MATH_TRUNC # In[1] import math # 数値の整数部分を取得 a = math.trunc(3.14) b = math.trunc(-3.14) c = math.trunc(10.0) print([a, b, c]) # [3, -3, 10]
コメント
下記は誤植と思われますので、ご確認ください。
「床関数」の下の文章で、⌊x⌋, floor(x), [x] などの記号 → ⌊x⌋, floor(x) の記号
ceil( ) や floor( ) の引数が負のときに、「0 に近いほうの整数」や「0 から遠いほうの整数」が返るという表現は、負数の大小を考える必要がなくていいと思いました。
ありがとうございます。
「0に近いほうの整数」「0から遠いほうの整数」は、床関数や天井関数を考えるときに私自身の頭が混乱しないように工夫した表現です。
【AI連載小説】科学とコードの交差点(10)
大学のラボで、六郷開誠と刑部明信は数値計算の最適化について情熱的に議論していた。特に、数値の切り捨て演算に関する最良の方法に焦点を当てていた。
開誠が興奮気味に言った。「数値計算で切り捨てをするとき、どの方法が一番効率的だと思う?」
明信は考え込みながら答えた。「確かに、切り捨ての方法は計算の結果に影響を与えることがある。Pythonでは math.floor() や int() を使うことが一般的だけど、どちらが優れているかはケースバイケースかな」
開誠はノートにメモを取りながら続けた。「確かに、どちらも精度に違いがあるし、計算速度も影響する。特に大量のデータに対して効率的な方法を見つけることが重要だよね」
明信は微笑みながら言った。「そうだね。また、ビジネス上の要件にも応じて適切な方法を選ぶことが求められる。例えば、処理速度が重要な場合と、結果の精度が優先される場合では違うだろう。」
二人はノートパソコンの画面に向かって、Pythonのコードを書き進めていった。開誠は新しいアプローチについてのアイデアを提案し、「例えば、numpyのtrunc()メソッドを使うことも考えられるよね。これは効率的で高速な切り捨てができるし、大規模なデータにも適している」と言った。
明信は興味津々で反応し、「そのアプローチは確かに魅力的だね。また、ビジネスのコンテキストによっては、クライアントやユーザーにとって意味のある切り捨て方法を採用することも重要だろう」
開誠は少し考え込んでから続けた。「それにしても、最適な方法を見つけるって奥が深いな。計算の速度、精度、ビジネスの要件、そしてどれだけコンピュータリソースを使えるかなど、多くの要因が影響する」