- # C言語/C++入門 > 演算子のオーバーロード
小数点以下1桁の計算を行うクラス・演算子オーバーロードの実験
スポンサーリンク
スポンサーリンク
ライフスタイル関連のコンテンツ
お金 | 仕事 | 勉強 | プライベート | 健康 | 心
プログラミング関連のコンテンツ
C言語/C++入門 | Ruby入門 | Python入門 | プログラミング全般
お金 | 仕事 | 勉強 | プライベート | 健康 | 心
プログラミング関連のコンテンツ
C言語/C++入門 | Ruby入門 | Python入門 | プログラミング全般
演算子オーバーロードの実験として、小数点以下1桁にそろえて乗算の計算結果を返すクラスを作ってみました。
スポンサーリンク
#include <iostream> #include <assert.h> #include <stdlib.h> // 内部的に小数点以下1桁の数字を整数で保持するために10を掛ける const int digit = 10; /********************************************************************* * 倍精度浮動小数点数を小数点以下1桁にするために加算する補正数字 * 浮動小数点数1.5は、コンピュータ内では1.4999999999...で保持されるため、 * 小数点以下2桁を切り捨てると1.4になってしまう。 * この問題を避けるために、補正係数として0.0001を足す *********************************************************************/ const double correct_num = 0.0001; /********************************************************************* * ptoneクラス * 乗算で小数点以下を1桁に固定するクラス * * オーバーロードする演算子をメンバ関数で定義 * f -- 固定小数点数 * s -- double型小数点数 * * // 乗算 * f = f * f; * f = s * f; * f = f * s; * * ostream << f // 出力 *********************************************************************/ class ptone { private: // 固定小数点の値(digit(10)をかけて内部的には整数で保持する) long int number; // double型を小数点以下1桁に変更する静的メンバ関数 static long int double2ptone(const double num_double) { return ( static_cast<long int>( // 4. 最終的にlong int型にキャスト num_double // 1. double型の浮動小数点数 * static_cast<double>(digit) // 2. digit(10)をdouble型にキャスト後かける + correct_num // 3. 補正係数を足す ) ); } public: // デフォルトコンストラクタ ptone() { number = 0; // numberを0にする } // コピーコンストラクタ ptone(const ptone& old_ptone) { number = old_ptone.number; // numberをold_ptone.numberにする } // doubleからptoneを生成。コンストラクタのオーバーロード ptone(const double num_real) { number = double2ptone(num_real); } // デストラクタ。何もしない。 ~ptone() { } /**************************** * メンバ関数を定義 ****************************/ // 数値を設定する void set(const double real) { number = double2ptone(real); } // 数値を取得。digit(10)で割る double get() const { return (static_cast<double>(number) / digit); } private: // 内部変換 ptone(const long int value) : number(value) {} // 乗算。* 演算子のオーバーロード friend ptone operator * (const ptone& ope1, const ptone& ope2); friend ptone operator * (const ptone& ope1, const double ope2); friend ptone operator * (const double ope1, const ptone& ope2); // 出力演算子 << のオーバーロード friend std::ostream& operator << (std::ostream& out, const ptone& numobj); }; // 乗算。* 演算子のオーバーロード ptone operator * (const ptone& ope1, const ptone& ope2) { return ptone(ope1.number * ope2.number / digit); } ptone operator * (const ptone& ope1, const double ope2) { return ptone(ope1.number * ptone::double2ptone(ope2) / digit); } ptone operator * (const double ope1, const ptone& ope2) { return ptone(ptone::double2ptone(ope1) * ope2.number / digit); } // 出力演算子 << のオーバーロード std::ostream& operator << (std::ostream& out, const ptone& numobj) { long int before_dp = numobj.number / digit; // 小数点の前部分 long int after_dp = abs(numobj.number % digit); // 小数点以下1桁目 out << before_dp << '.' << after_dp; // 整形して1桁小数点数を出力 return (out); } // テスト用ルーチン int main() { ptone result_a(2.3 * 4.682); // 10.7 が期待される ptone result_b(0.00005 * 3); // 0.0 が期待される ptone result_c(3.0 * 4); // 12.0 が期待される std::cout << result_a << std::endl; std::cout << result_b << std::endl; std::cout << result_c << std::endl; std::cout << result_a * result_c << std::endl; // 128.4 が期待される return 0; }
テスト用ルーチンのとおり、* 演算子はオーバーロードされていますので、計算結果では小数点以下が1桁にフォーマットされて出力されるはずです。
実行結果。
10.7 0.0 12.0 128.4
ちゃんと出力されました。
演算子のオーバーロードは、いろいろな演算子で可能ですので、必要となったら後学することにします。
以下のページがとても分かりやすい。
参考:
C++マニアック,オペレータのオーバーロード,operator overload,演算子のオーバーロード,演算子
スポンサーリンク
<< 前の記事 : オーバーロードが可能な演算子
スポンサーリンク