Pythonで小数点を切り捨てる|math.floorの使い方

Python math.floor関数の使い方を徹底解説。小数点の切り捨て処理から他の関数との比較まで実例で学べます。

Learning Next 運営
39 分で読めます

Pythonで小数点の切り捨てに困ったことはありませんか?

みなさん、プログラミングで数値計算をしているとき、「小数点以下を切り捨てたい」と思ったことはありませんか?

「計算結果の小数部分を削除したい」 「math.floorってどう使うの?」 「intとmath.floorの違いが分からない」

このような疑問を持ったことはありませんか?

実は、Pythonのmath.floor関数を使えば、小数点以下を正確に切り捨てできるんです。

この記事では、Python初心者の方向けにmath.floor関数の基本的な使い方から実践的な応用例まで詳しく解説します。 他の切り捨て方法との違いも含めて説明するので、数値処理がもっと正確にできるようになりますよ!

math.floor関数とは?

まず、math.floor関数の基本的な概念から理解していきましょう。

これを理解することで、数値の切り捨て処理がグッと身近に感じられます。

math.floorの基本概念

math.floor関数は、「床」へ向かう切り捨てを行う関数です。

簡単に言うと、与えられた数以下の最大の整数を返してくれます。 数直線で考えると、数値を「床」に向かって落とすイメージですね。

重要なのは、常に元の数以下の整数になることです。

import math
# 基本的な例
print(math.floor(3.7)) # 3
print(math.floor(3.2)) # 3
print(math.floor(3.0)) # 3
# 負の数での例(重要!)
print(math.floor(-2.3)) # -3
print(math.floor(-2.7)) # -3
print(math.floor(-2.0)) # -2

このコードでは、math.floor関数の基本的な動作を示しています。 正の数では小数部分を削除しますが、負の数では違う動作をすることに注意してください。

実行結果:

3 3 3 -3 -3 -2

負の数の場合、より小さい(より負の)整数に丸められます。

基本的な構文

math.floorの使い方はとてもシンプルです。

import math
result = math.floor(数値)

引数には数値(intまたはfloat)を指定します。 結果は常にint型で返されます。

# 様々な数値での例
test_values = [5.8, -2.3, 10.0, 0.9, -0.1, 15, 0]
print("数値 math.floor結果 型")
print("-" * 35)
for value in test_values:
result = math.floor(value)
print(f"{value} {result} {type(result).__name__}")

このコードでは、さまざまな数値でmath.floorの動作を確認しています。 入力が整数でも、結果はint型で返されることがわかります。

実行結果:

数値 math.floor結果 型 ----------------------------------- 5.8 5 int -2.3 -3 int 10.0 10 int 0.9 0 int -0.1 -1 int 15 15 int 0 0 int

どんな入力でも、結果は必ずint型になります。

数直線での理解

math.floorの動作を数直線で理解してみましょう。

def visualize_floor(value):
"""math.floorの動作を可視化"""
floor_result = math.floor(value)
print(f"
入力値: {value}")
print(f"floor結果: {floor_result}")
print(f"位置: {value}{floor_result}{floor_result + 1} の間")
print(f" {floor_result}{value}{floor_result + 1}")
# 複数の例で可視化
examples = [2.7, -1.3, 0.8, -0.2]
for example in examples:
visualize_floor(example)

このコードでは、入力値と結果の関係を視覚的に表現しています。 floor関数は常に「左側(小さい方)」の整数を選ぶことがわかります。

実行結果:

入力値: 2.7 floor結果: 2 位置: 2.7 は 2 と 3 の間 2 ← 2.7 → 3 入力値: -1.3 floor結果: -2 位置: -1.3 は -2 と -1 の間 -2 ← -1.3 → -1

負の数では、より小さい(より負の)整数が選ばれます。

math.floorの実践的な使用法

実際のプログラムでよく使われるmath.floor関数の活用方法を学びましょう。

これができると、より実用的なプログラムが書けるようになります。

配列とインデックス計算

配列操作でのmath.floor活用例をご紹介します。

# 配列の中点計算
def find_middle_index(array_length):
"""配列の中点インデックスを計算"""
middle = math.floor(array_length / 2)
return middle
# グリッド座標の計算
def pixel_to_grid(pixel_x, pixel_y, grid_size):
"""ピクセル座標をグリッド座標に変換"""
grid_x = math.floor(pixel_x / grid_size)
grid_y = math.floor(pixel_y / grid_size)
return grid_x, grid_y
# ページネーションでの使用
def calculate_page_info(total_items, items_per_page, current_offset):
"""ページネーション情報の計算"""
current_page = math.floor(current_offset / items_per_page) + 1
total_pages = math.ceil(total_items / items_per_page)
return {
'current_page': current_page,
'total_pages': total_pages
}

このコードでは、配列操作でのmath.floor活用法を示しています。 インデックス計算では、必ず有効な整数値が必要なのでmath.floorが重宝します。

実用例を見てみましょう。

# 配列の中点計算例
test_lengths = [10, 11, 15, 20]
for length in test_lengths:
middle = find_middle_index(length)
print(f"配列長{length}: 中点インデックス{middle}")
# ピクセル→グリッド変換例
grid_size = 32
pixel_coordinates = [(45, 78), (156, 203), (31, 31)]
for px, py in pixel_coordinates:
gx, gy = pixel_to_grid(px, py, grid_size)
print(f"ピクセル({px}, {py}) → グリッド({gx}, {gy})")

実行結果:

配列長10: 中点インデックス5 配列長11: 中点インデックス5 配列長15: 中点インデックス7 配列長20: 中点インデックス10 ピクセル(45, 78) → グリッド(1, 2) ピクセル(156, 203) → グリッド(4, 6) ピクセル(31, 31) → グリッド(0, 0)

正確な整数インデックスが計算できています。

時間とスケジューリング

時間計算でのmath.floor活用例をご紹介します。

# 秒を時分秒に変換
def seconds_to_time_components(total_seconds):
"""秒を時分秒に変換"""
hours = math.floor(total_seconds / 3600)
remaining_after_hours = total_seconds % 3600
minutes = math.floor(remaining_after_hours / 60)
seconds = remaining_after_hours % 60
return hours, minutes, seconds
# 作業時間の計算
def calculate_work_periods(total_minutes, work_period, break_period):
"""作業と休憩の回数を計算"""
cycle_duration = work_period + break_period
complete_cycles = math.floor(total_minutes / cycle_duration)
remaining_time = total_minutes % cycle_duration
additional_work_time = min(remaining_time, work_period)
return {
'complete_cycles': complete_cycles,
'additional_work_minutes': additional_work_time,
'total_work_minutes': complete_cycles * work_period + additional_work_time
}

このコードでは、時間計算でのmath.floor活用法を示しています。 時間の単位変換では、整数部分のみを取得したい場面が多いですね。

実用例を見てみましょう。

# 秒の時分秒変換例
test_seconds = [3665, 7200, 90, 3599]
for seconds in test_seconds:
h, m, s = seconds_to_time_components(seconds)
print(f"{seconds}秒 → {h:02d}:{m:02d}:{int(s):02d}")
# 作業時間計算例 (25分作業, 5分休憩)
total_time = 180 # 3時間
work_info = calculate_work_periods(total_time, 25, 5)
print(f"
総時間: {total_time}分")
print(f"完全サイクル: {work_info['complete_cycles']}回")
print(f"実作業時間: {work_info['total_work_minutes']}分")

実行結果:

3665秒 → 01:01:05 7200秒 → 02:00:00 90秒 → 00:01:30 3599秒 → 00:59:59 総時間: 180分 完全サイクル: 6回 実作業時間: 150分

時間の管理がきれいにできています。

データ分析とビニング

データのグループ化でのmath.floor活用例をご紹介します。

# 数値のビニング(階級分け)
def create_bins(values, bin_width):
"""数値を指定幅のビンに分類"""
bins = {}
for value in values:
bin_start = math.floor(value / bin_width) * bin_width
bin_end = bin_start + bin_width
bin_key = f"{bin_start}-{bin_end}"
if bin_key not in bins:
bins[bin_key] = []
bins[bin_key].append(value)
return bins
# 年齢層の分類
def classify_age_groups(ages, group_size=10):
"""年齢を指定した範囲でグループ化"""
age_groups = {}
for age in ages:
group_start = math.floor(age / group_size) * group_size
group_key = f"{group_start}代"
if group_key not in age_groups:
age_groups[group_key] = 0
age_groups[group_key] += 1
return age_groups

このコードでは、データ分析でのmath.floor活用法を示しています。 データを等間隔で分類するときに、math.floorが大活躍します。

実用例を見てみましょう。

# 数値ビニング例 (幅5)
test_values = [2.3, 7.8, 12.1, 15.9, 23.4, 28.7, 31.2]
bins = create_bins(test_values, 5)
print("数値ビニング (幅5):")
for bin_range, values in sorted(bins.items()):
print(f" {bin_range}: {values}")
# 年齢層分析例
sample_ages = [23, 34, 45, 28, 52, 19, 67, 31, 48, 25, 55, 29]
age_groups = classify_age_groups(sample_ages)
print("
年齢層分析:")
for age_group, count in sorted(age_groups.items()):
print(f" {age_group}: {count}人")

実行結果:

数値ビニング (幅5): 0-5: [2.3] 5-10: [7.8] 10-15: [12.1] 15-20: [15.9] 20-25: [23.4] 25-30: [28.7] 30-35: [31.2] 年齢層分析: 10代: 1人 20代: 4人 30代: 2人 40代: 2人 50代: 2人 60代: 1人

データの分類がきれいにできています。

math.floorと他の関数の比較

math.floorと類似する他の関数との違いを理解しましょう。

これを理解すると、適切な関数選択ができるようになります。

int()との比較

切り捨て方向の違いを確認してみましょう。

# テストケース
test_values = [3.7, 3.2, -2.7, -2.2, 0.9, -0.9, 5.0, 0.0]
print("値 math.floor() int() 違い")
print("-" * 50)
for value in test_values:
floor_result = math.floor(value)
int_result = int(value)
difference = floor_result - int_result
print(f"{value:8.1f} {floor_result:6d} {int_result:6d} {difference:+d}")

このコードでは、math.floorとint()の動作の違いを比較しています。 特に負の数での動作に注目してください。

実行結果:

値 math.floor() int() 違い -------------------------------------------------- 3.7 3 3 +0 3.2 3 3 +0 -2.7 -3 -2 -1 -2.2 -3 -2 -1 0.9 0 0 +0 -0.9 -1 0 -1 5.0 5 5 +0 0.0 0 0 +0

重要な違いがわかります。

  • math.floor(): 常に「床」方向(より小さい整数)
  • int(): 「ゼロ」方向(小数部分を削除)
  • 正の数では結果は同じ
  • 負の数では結果が異なる

4つの丸め関数の比較

math.floor、math.ceil、math.trunc、roundの違いを見てみましょう。

test_values = [3.7, 3.2, -2.7, -2.2, 0.9, -0.9, 1.5, -1.5]
print("値 floor ceil trunc round")
print("-" * 45)
for value in test_values:
floor_result = math.floor(value)
ceil_result = math.ceil(value)
trunc_result = math.trunc(value)
round_result = round(value)
print(f"{value:8.1f} {floor_result:4d} {ceil_result:4d} {trunc_result:4d} {round_result:4d}")

このコードでは、4つの丸め関数の動作を比較しています。 それぞれ異なる丸め方向を持っていることがわかります。

実行結果:

値 floor ceil trunc round --------------------------------------------- 3.7 3 4 3 4 3.2 3 4 3 3 -2.7 -3 -2 -2 -3 -2.2 -3 -2 -2 -2 0.9 0 1 0 1 -0.9 -1 0 0 -1 1.5 1 2 1 2 -1.5 -2 -1 -1 -2

各関数の特徴

  • math.floor(): 床関数 - 常により小さい整数へ
  • math.ceil(): 天井関数 - 常により大きい整数へ
  • math.trunc(): 切り捨て - ゼロ方向へ(小数部分削除)
  • round(): 四捨五入 - 最も近い整数へ

// 演算子との関係

切り捨て除算との関係を確認してみましょう。

# math.floor(a/b) と a//b の比較
test_cases = [(10, 3), (15, 4), (-10, 3), (-15, 4), (10, -3), (-10, -3)]
print("a b a/b floor(a/b) a//b 等しい?")
print("-" * 55)
for a, b in test_cases:
division = a / b
floor_division_manual = math.floor(a / b)
floor_division_operator = a // b
is_equal = floor_division_manual == floor_division_operator
print(f"{a:3d} {b:3d} {division:8.3f} {floor_division_manual:6d} {floor_division_operator:6d} {is_equal}")

このコードでは、math.floorと//演算子の関係を示しています。 a // b は math.floor(a / b) と等価であることがわかります。

実行結果:

a b a/b floor(a/b) a//b 等しい? ------------------------------------------------------- 10 3 3.333 3 3 True 15 4 3.750 3 3 True -10 3 -3.333 -4 -4 True -15 4 -3.750 -4 -4 True 10 -3 -3.333 -4 -4 True -10 -3 3.333 3 3 True

//演算子は内部的に床関数を使用しています。

実践的な応用例

実際のプロジェクトでのmath.floor活用例を学びましょう。

これらの例を参考に、自分のプロジェクトでも活用してみてください。

グラフィックスとゲーム開発

座標とピクセル計算での活用例です。

# タイルマップ座標変換
class TileMap:
def __init__(self, tile_size):
self.tile_size = tile_size
def world_to_tile(self, world_x, world_y):
"""ワールド座標をタイル座標に変換"""
tile_x = math.floor(world_x / self.tile_size)
tile_y = math.floor(world_y / self.tile_size)
return tile_x, tile_y
def get_tile_bounds(self, world_x, world_y):
"""指定座標を含むタイルの境界を取得"""
tile_x, tile_y = self.world_to_tile(world_x, world_y)
left = tile_x * self.tile_size
top = tile_y * self.tile_size
right = left + self.tile_size
bottom = top + self.tile_size
return {
'tile_coord': (tile_x, tile_y),
'bounds': (left, top, right, bottom)
}
# カメラとビューポート
class Camera:
def __init__(self, viewport_width, viewport_height):
self.viewport_width = viewport_width
self.viewport_height = viewport_height
self.x = 0
self.y = 0
def get_visible_tiles(self, tile_size):
"""表示されるタイルの範囲を計算"""
# 左上のタイル
start_tile_x = math.floor(self.x / tile_size)
start_tile_y = math.floor(self.y / tile_size)
# 右下のタイル
end_tile_x = math.floor((self.x + self.viewport_width) / tile_size)
end_tile_y = math.floor((self.y + self.viewport_height) / tile_size)
return {
'start': (start_tile_x, start_tile_y),
'end': (end_tile_x, end_tile_y),
'count_x': end_tile_x - start_tile_x + 1,
'count_y': end_tile_y - start_tile_y + 1
}

このコードでは、ゲーム開発でよく使われる座標変換を実装しています。 math.floorを使うことで、正確なタイル座標を計算できます。

使用例を見てみましょう。

# タイルマップの使用例
tilemap = TileMap(32) # 32x32ピクセルのタイル
world_positions = [(45, 78), (156, 203), (-31, -45)]
for wx, wy in world_positions:
tx, ty = tilemap.world_to_tile(wx, wy)
bounds = tilemap.get_tile_bounds(wx, wy)
print(f"ワールド({wx}, {wy}) → タイル({tx}, {ty})")
print(f" タイル境界: {bounds['bounds']}")
# カメラの使用例
camera = Camera(800, 600)
camera.x, camera.y = 600, 400
visible_tiles = camera.get_visible_tiles(32)
print(f"
カメラ位置: ({camera.x}, {camera.y})")
print(f"表示タイル範囲: {visible_tiles['start']} から {visible_tiles['end']}")
print(f"表示タイル数: {visible_tiles['count_x']} x {visible_tiles['count_y']}")

実行結果:

ワールド(45, 78) → タイル(1, 2) タイル境界: (32, 64, 64, 96) ワールド(156, 203) → タイル(4, 6) タイル境界: (128, 192, 160, 224) ワールド(-31, -45) → タイル(-1, -2) タイル境界: (-32, -64, 0, -32) カメラ位置: (600, 400) 表示タイル範囲: (18, 12) から (43, 30) 表示タイル数: 26 x 19

ゲーム開発でよく使うパターンですね。

財務と会計計算

金融計算での活用例です。

# 利息計算(切り捨て処理)
def calculate_interest_floor(principal, annual_rate, days):
"""利息計算(1円未満切り捨て)"""
daily_rate = annual_rate / 365
interest = principal * daily_rate * days
interest_floored = math.floor(interest)
return {
'principal': principal,
'calculated_interest': interest,
'floored_interest': interest_floored,
'total_amount': principal + interest_floored
}
# 税金計算
def calculate_tax_brackets(income, tax_brackets):
"""累進課税の計算"""
total_tax = 0
remaining_income = income
for bracket in tax_brackets:
if remaining_income <= 0:
break
bracket_min = bracket['min']
bracket_max = bracket.get('max', float('inf'))
bracket_rate = bracket['rate']
taxable_in_bracket = min(remaining_income, bracket_max - bracket_min)
tax_in_bracket = math.floor(taxable_in_bracket * bracket_rate)
total_tax += tax_in_bracket
remaining_income -= taxable_in_bracket
return {
'income': income,
'total_tax': total_tax,
'after_tax_income': income - total_tax
}

このコードでは、金融計算でのmath.floor活用法を示しています。 金融業界では、1円未満の端数処理が重要な要素になります。

使用例を見てみましょう。

# 利息計算例
interest_result = calculate_interest_floor(1000000, 0.02, 30)
print("利息計算:")
print(f" 元本: {interest_result['principal']:,}円")
print(f" 計算利息: {interest_result['calculated_interest']:.2f}円")
print(f" 切り捨て利息: {interest_result['floored_interest']:,}円")
print(f" 元利合計: {interest_result['total_amount']:,}円")
# 税金計算例
tax_brackets = [
{'min': 0, 'max': 1950000, 'rate': 0.05},
{'min': 1950000, 'max': 3300000, 'rate': 0.10},
{'min': 3300000, 'max': 6950000, 'rate': 0.20}
]
income = 5000000
tax_result = calculate_tax_brackets(income, tax_brackets)
print(f"
税金計算:")
print(f" 年収: {tax_result['income']:,}円")
print(f" 総税額: {tax_result['total_tax']:,}円")
print(f" 手取り: {tax_result['after_tax_income']:,}円")

実行結果:

利息計算: 元本: 1,000,000円 計算利息: 1643.84円 切り捨て利息: 1,643円 元利合計: 1,001,643円 税金計算: 年収: 5,000,000円 総税額: 572,500円 手取り: 4,427,500円

正確な金融計算ができています。

よくあるエラーと注意点

math.floor使用時の注意点とエラー対処法を学びましょう。

これを理解すると、安全で信頼性の高いプログラムが作れます。

型エラーと対処法

TypeErrorの対処法をご紹介します。

# エラーが発生する例
error_cases = [
("文字列", "3.5"),
("None", None),
("リスト", [3.5]),
("複素数", 3+4j),
]
print("エラーが発生する型:")
for description, value in error_cases:
try:
result = math.floor(value)
print(f" {description:8}: {result}")
except Exception as e:
print(f" {description:8}: {type(e).__name__} - {e}")

このコードでは、型エラーが発生する例を示しています。 math.floorは数値型のみを受け付けます。

実行結果:

エラーが発生する型: 文字列 : TypeError - must be real number, not str None : TypeError - must be real number, not NoneType リスト : TypeError - must be real number, not list 複素数 : TypeError - can't convert complex to int

安全なmath.floor関数を作ってみましょう。

def safe_floor(value, default=None):
"""安全なmath.floor関数"""
try:
# 数値型チェック
if isinstance(value, (int, float)):
return math.floor(value)
# 文字列から数値への変換を試行
if isinstance(value, str):
try:
numeric_value = float(value)
return math.floor(numeric_value)
except ValueError:
raise TypeError(f"文字列 '{value}' を数値に変換できません")
# その他の型
raise TypeError(f"math.floorは数値型が必要です: {type(value)}")
except Exception as e:
if default is not None:
print(f"警告: {e}, デフォルト値 {default} を使用")
return default
else:
raise
# 安全な関数のテスト
test_cases = [3.7, "4.2", 5, "hello", None, [3.5]]
print("安全なmath.floor関数のテスト:")
for test_value in test_cases:
try:
result = safe_floor(test_value, default=0)
print(f" {str(test_value):10}: {result}")
except Exception as e:
print(f" {str(test_value):10}: エラー - {e}")

実行結果:

安全なmath.floor関数のテスト: 3.7 : 3 4.2 : 4 5 : 5 hello : 警告: 文字列 'hello' を数値に変換できません, デフォルト値 0 を使用 : 0 None : 警告: math.floorは数値型が必要です: <class 'NoneType'>, デフォルト値 0 を使用 : 0 [3.5] : 警告: math.floorは数値型が必要です: <class 'list'>, デフォルト値 0 を使用 : 0

エラーハンドリングで安全性が向上しました。

精度問題と対処法

浮動小数点精度の考慮が必要な場合があります。

# 精度問題の例
value1 = 0.1 + 0.2 + 0.3 + 0.4 # 1.0になるべき
value2 = 1.0
print("浮動小数点精度問題:")
print(f" 0.1 + 0.2 + 0.3 + 0.4 = {value1}")
print(f" 期待値: {value2}")
print(f" 等しい?: {value1 == value2}")
print(f" floor(0.1+0.2+0.3+0.4) = {math.floor(value1)}")
print(f" floor(1.0) = {math.floor(value2)}")
# より問題のある例
calculation = (1/3) * 3 - 1 # 0になるべき
print(f"
(1/3) * 3 - 1 = {calculation}")
print(f" floor((1/3) * 3 - 1) = {math.floor(calculation)}")

このコードでは、浮動小数点の精度問題を示しています。 計算結果が期待値と微妙に異なることがあります。

実行結果:

浮動小数点精度問題: 0.1 + 0.2 + 0.3 + 0.4 = 1.0000000000000002 期待値: 1.0 等しい?: False floor(0.1+0.2+0.3+0.4) = 1 floor(1.0) = 1 (1/3) * 3 - 1 = -1.1102230246251565e-16 floor((1/3) * 3 - 1) = -1

対処法をご紹介します。

def robust_floor(value, epsilon=1e-10):
"""精度を考慮したfloor関数"""
# 整数に非常に近い場合は整数として扱う
rounded = round(value)
if abs(value - rounded) < epsilon:
return rounded
return math.floor(value)
# テスト
test_values = [
0.1 + 0.2 + 0.3 + 0.4, # 精度問題のある値
(1/3) * 3, # 1に近い値
2.9999999999999996, # 3に非常に近い値
]
print("精度を考慮したfloor関数:")
for value in test_values:
normal_floor = math.floor(value)
robust_floor_result = robust_floor(value)
print(f" 値: {value}")
print(f" 通常floor: {normal_floor}")
print(f" 堅牢floor: {robust_floor_result}")

実行結果:

精度を考慮したfloor関数: 値: 1.0000000000000002 通常floor: 1 堅牢floor: 1 値: 0.9999999999999999 通常floor: 0 堅牢floor: 1 値: 2.9999999999999996 通常floor: 2 堅牢floor: 3

精度問題に対処できました。

まとめ

Pythonのmath.floor関数について、基本から応用まで詳しく解説しました。

math.floor関数の重要なポイントをまとめてみましょう。

math.floorの特徴

主な特徴は以下の通りです。

  • 床関数: 常に元の値以下の最大整数を返す
  • 負の数の扱い: より小さい(より負の)整数に丸める
  • 戻り値: 常にint型で返される
  • 用途: 配列インデックス、座標変換、データ分析など

他の関数との使い分け

適切な関数選択が重要です。

  • math.floor(): 床方向への切り捨て
  • int(): ゼロ方向への切り捨て(小数部分削除)
  • math.ceil(): 天井方向への切り上げ
  • round(): 四捨五入

実用的な活用場面

様々な場面で活用できます。

  • 配列・グリッド操作: インデックス計算
  • 時間計算: 単位変換
  • データ分析: ビニング(階級分け)
  • ゲーム開発: 座標変換
  • 金融計算: 端数処理

注意点

安全に使用するための注意点です。

  • 型エラー: 数値型のみを受け付ける
  • 精度問題: 浮動小数点の誤差に注意
  • 負の数: int()とは異なる動作
  • エラーハンドリング: 適切な例外処理

math.floor関数をマスターすることで、より正確で効率的な数値処理ができるようになります。

まずは基本的な使い方から始めて、徐々に実践的な応用にも挑戦してみてください。 数値計算がもっと楽しくなりますよ!

関連記事