剰余と切り捨て除算

このレッスンで作るもの — 割り算の答えを整数と余りに分ける //% を覚え、飲み会の割り勘を計算します。

剰余と切り捨て除算

第 1 章で扱った割り算 / には、少し困ったところがあります。

print(1000 / 3) # 333.3333333333333

1000 円を 3 人で割ると 333.3333... 円。お金にこの答えは使えません。実際にほしいのは「1 人 333 円ずつ出して、1 円あまる」という形です。

これを出すのが 切り捨て除算//剰余% です。

/ はいつでも小数 (float) を返します。10 / 2 ですら 5.0 です。整数がほしい場面では // を使います。

// は商、% は余り

// は割り算の答えの小数部分を切り捨てて、整数だけを返します。% は割ったときの余りを返します。

print(1000 // 3) # 333 print(1000 % 3) # 1

333 × 3 = 9991000 - 999 = 1 なので、確かに 1 あまります。この 2 つは常にセットで、割られる数 == 商 * 割る数 + 余り の関係が成り立ちます。

print(250 // 4) # 62 print(250 % 4) # 2 print(62 * 4 + 2) # 250 に戻る

% は「パーセント」の記号ですが、Python では百分率とは何の関係もありません。読み方は「モジュロ」または「あまり」です。

割り切れるかを調べる

% のいちばん有名な使い道が「割り切れるか」の判定です。余りが 0 なら割り切れています。

print(10 % 2 == 0) # True 偶数 print(7 % 2 == 0) # False 奇数

% 2 で偶数と奇数を分ける、% 3 で 3 の倍数を見つける。第 4 章でやる FizzBuzz はこの応用そのものです。

diagram (will load when visible)

動きを追ってみる

split_bill(1000, 3) の流れを追います。

  1. total1000people3 が入る
  2. total // people333 になる
  3. total % people1 になる
  4. その 2 つを f-string に埋め込んで "1人 333円 あまり 1円" を組み立てる
  5. その文字列を return する

第 2 章で覚えた f-string がここで効きます。f"..." の中では {} の中身が計算されて文字列に変わるので、str() で包み直す必要がありません。

def split_bill(total, people): return f"1人 {total // people}円 あまり {total % people}円"

{} の中に total // people のような をそのまま書けるところがポイントです。いったん変数に入れてから埋めても構いません。読みやすいほうを選んでください。

本当は「1 人分」と「あまり」という 2 つの数値をそのまま返したいところです。値を 2 つ同時に返す書き方は第 6 章で扱います。今日は 1 本の文字列にまとめて返します。

負の数での挙動

Python// は、小数点以下を切り捨てるのではなく 小さいほうへ丸めます。負の数だと直感と違う答えになります。

print(-7 // 2) # -4 (-3.5 より小さい整数) print(-7 % 2) # 1

おこづかい帳では金額が負になることはないので実害はありませんが、「切り捨て」という言葉から -3 を期待すると裏切られる、とだけ覚えておいてください。

よくある間違い

  1. /// の取り違え1000 / 3333.3333333333333 という小数です。f"{1000 / 3}円" と書くと、とんでもない見た目になります。整数がほしいときは // です。
  2. 0 で割ってしまう10 // 010 % 0ZeroDivisionError になります。人数のように「0 になりうる値」で割るときは注意が必要です。
  3. % を百分率と思い込む50 % 100 は「50 パーセント」ではなく「50 を 100 で割った余りの 50」です。

エラーの名前は読めば意味が分かるように付いています。ZeroDivisionError は「ゼロで割った」とそのまま書いてあります。焦らず読むのがいちばん速い解決です。

やってみよう

関数 split_bill(total, people) を実装してください。total 円を people 人で割り勘したときの結果を、下記の形の文字列で返します。

1人 333円 あまり 1円

1人 のあとに 1 人あたりの金額、円 あまり のあとに余りの金額、最後に です。半角スペースの位置に注意してください。total = 1000people = 3 なら上のとおり、total = 3000people = 3 なら 1人 1000円 あまり 0円 になります。割り切れるときも あまり 0円 と表示します。

要件

  1. 関数名は split_bill で、引数は total と people の2つ
  2. 1人あたりの金額は // で求める(/ を使うと小数になる)
  3. 端数は % で求め、割り切れるときも あまり 0円 と表示する
  4. 戻り値は "1人 333円 あまり 1円" と同じ形の文字列にする

入出力例

split_bill(1000, 3)"1人 333円 あまり 1円" split_bill(3000, 3)"1人 1000円 あまり 0円" split_bill(250, 4)"1人 62円 あまり 2円" split_bill(100, 1)"1人 100円 あまり 0円" split_bill(0, 3)"1人 0円 あまり 0円" split_bill(5, 10)"1人 0円 あまり 5円"

ヒント

生田 陸人
ゆめさくエンジニア / 現役ソフトウェアエンジニア
編集 LuaGate編集部
main.py
main.py
学習モード

メモ

剰余と切り捨て除算

⌘S で保存