Code Fix

初級

int同士の割り算で小数点以下が消えるバグ

int型同士の割り算は小数点以下を切り捨てたint型の結果になるバグです。その結果をdouble型に代入しても、切り捨てはすでに終わったあとなので元には戻りません。

なぜエラーが出ないのか

出力: 3.0
(エラーなし)
C++は何も報告しません。コンパイルも実行も正常に完了するためです
出力: 3.0
実際の挙動 — 期待した結果と食い違っている箇所
見つけ方
エラーが出ないので、出力を目で確かめるか、コードを目で追うしかありません。この種の誤りが最も発見が遅れます

このエラーが出る典型パターン

パターン1

 1  #include <iostream>
 2  #include <iomanip>
 3  int main() {
 4      int total = 7;
 5      int count = 2;
 6      double avg = total /       count;
                              ^
 7      std::cout << std::fixed << std::setprecision(1) << avg << std::endl;
 8      return 0;
 9  }
出力: 3.0期待: 3.5

int同士の割り算は小数点以下を切り捨てたint型の結果になります。その結果をdoubleに代入しても、切り捨てはすでに終わったあとで元には戻りません。片方をdoubleにキャストしてから割る必要があります。

直し方: // 1.0 / にします。

この問題を解いてみる →

広告
広告スロット(未設定)

パターン2

 1  #include <iostream>
 2  #include <iomanip>
 3  int main() {
 4      int minutes = 100;
 5      double hours = minutes /       60;
                                  ^
 6      std::cout << std::fixed << std::setprecision(2) << hours << std::endl;
 7      return 0;
 8  }
出力: 1.00期待: 1.67

minutesと60はどちらもint型なので、/は整数の割り算になり小数点以下が切り捨てられます。結果はdouble型の変数に代入されても、切り捨てられたあとの値がそのまま入るだけです。

直し方: // 1.0 / にします。

この問題を解いてみる →

パターン3

 1  #include <iostream>
 2  #include <iomanip>
 3  int main() {
 4      int price = 999;
 5      int people = 4;
 6      double share = price /       people;
                                ^
 7      std::cout << std::fixed << std::setprecision(2) << share << std::endl;
 8      return 0;
 9  }
出力: 249.00期待: 249.75

999 / 4は整数の割り算として計算され249になり、そのあとでdoubleに変換されます。先にdoubleへ変換してから割らなければ、小数部分は復元できません。

直し方: // 1.0 / にします。

この問題を解いてみる →

よくある誤解

「代入先がdouble型なら自動的に小数の割り算になる」というのは誤解です。C++は代入する直前ではなく、演算そのものを行う時点でのオペランドの型を見て割り算の種類を決めます。

まとめ

int同士の割り算で小数点以下が消えるバグは初級でつまずきやすい項目です。上の3パターンを実際に手で直すと、エラーメッセージのどこを読めばよいかが掴めます。

演習をはじめる

関連するエラー

広告
広告スロット(未設定)