- # 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,演算子のオーバーロード,演算子
スポンサーリンク
<< 前の記事 : オーバーロードが可能な演算子
スポンサーリンク