開発環境
- OS X Mavericks - Apple, ときどき
Windows 8.1 + Cygwin64, MinGW (OS)
- Emacs (CUI)、BBEdit - Bare Bones Software, Inc. (GUI) (Text Editor)
- C++ (プログラミング言語)
- g++(コンパイラ)
C++実践プログラミング (スティーブ オウアルライン (著)、Steve Oualline (原著)、Steve Oualline(原著)、望月 康司(翻訳)、クイープ(翻訳) 、オライリー・ジャパン)のⅤ部(言語のその他の機能)の22章(例外)、22.3(プログラミング実習)、実習 22-2.を解いてみる。
その他参考書籍
- C++プログラミング入門 (グレゴリー サティア (著)、ダウグ ブラウン (著)、Gregory Satir (原著)、Doug Brown (原著)、望月 康司 (翻訳)、谷口 功 (翻訳)、オライリージャパン)
実習 22-2.
コード(BBEdit, Emacs)
fraction.h
#ifndef __fraction_h__
#define __fraction_h__
#include <iostream>
#include <cstdlib>
class zero_div_err {
public:
const std::string what;
zero_div_err(const std::string& i_what) : what(i_what) {}
};
class fraction {
private:
int n;
int d;
static int gcd(int m, int n)
{
int t;
m = m < 0 ? -m : m;
n = n < 0 ? -n : n;
if (m < n) {
t = m;
m = n;
n = t;
}
if (n == 0)
return m;
return gcd(n, m % n);
}
public:
fraction() {
n = 0;
d = 1;
}
fraction(int a, int b) {
if (b == 0) {
throw zero_div_err("division by zero");
}
int t = gcd(a, b);
n = a / t;
d = b / t;
}
fraction(const fraction& old_fraction) {
fraction(old_fraction.n, old_fraction.d);
}
~fraction(){}
fraction operator = (const fraction& old_fraction) {
n = old_fraction.n;
d = old_fraction.d;
return (*this);
}
fraction& operator += (const fraction& old_fraction) {
(*this) = (*this) + old_fraction;
return (*this);
}
fraction& operator += (int x) {
(*this) = (*this) + fraction(x, 1);
return (*this);
}
fraction& operator -= (const fraction& old_fraction) {
(*this) = (*this) - old_fraction;
return (*this);
}
fraction& operator -= (int x) {
(*this) = (*this) - fraction(x, 1);
return (*this);
}
fraction& operator *= (const fraction& old_fraction) {
(*this) = (*this) * old_fraction;
return (*this);
}
fraction& operator *= (int x) {
(*this) = (*this) * fraction(x, 1);
return (*this);
}
fraction& operator /= (const fraction& old_fraction) {
(*this) = (*this) / old_fraction;
return (*this);
}
fraction& operator /= (int x) {
(*this) = (*this) / fraction(x, 1);
return (*this);
}
friend fraction operator + (const fraction& op1, const fraction& op2);
friend fraction operator + (const fraction& op1, int op2);
friend fraction operator + (int op1, const fraction& op2);
friend fraction operator - (const fraction& op1, const fraction& op2);
friend fraction operator - (const fraction& op1, int op2);
friend fraction operator - (int op1, const fraction& op2);
friend fraction operator * (const fraction& op1, const fraction& op2);
friend fraction operator * (const fraction& op1, int op2);
friend fraction operator * (int op1, const fraction& op2);
friend fraction operator / (const fraction& op1, const fraction& op2);
friend fraction operator / (const fraction& op1, int op2);
friend fraction operator / (int op1, const fraction& op2);
friend std::ostream& operator << (std::ostream& out_file,
const fraction& r);
friend std::istream& operator >> (std::istream& in_file,
fraction& r);
};
inline fraction operator + (const fraction& op1, const fraction& op2) {
int n1 = op1.n;
int d1 = op1.d;
int n2 = op2.n;
int d2 = op2.d;
int n = n1 * d2 + n2 * d1;
int d = d1 * d2;
int t = fraction::gcd(n, d);
return fraction(n / t, d / t);
}
inline fraction operator + (const fraction& op1, int op2) {
return op1 + fraction(op2, 1);
}
inline fraction operator + (int op1, const fraction& op2) {
return fraction(op1, 1) + op2;
}
inline fraction operator - (const fraction& op1, const fraction& op2) {
int n1 = op1.n;
int d1 = op1.d;
int n2 = op2.n;
int d2 = op2.d;
int n = n1 * d2 - n2 * d1;
int d = d1 * d2;
int t = fraction::gcd(n, d);
return fraction(n / t, d / t);
}
inline fraction operator - (const fraction& op1, int op2) {
return op1 - fraction(op2, 1);
}
inline fraction operator - (int op1, const fraction& op2) {
return fraction(op1, 1) - op2;
}
inline fraction operator * (const fraction& op1, const fraction& op2) {
int n1 = op1.n;
int d1 = op1.d;
int n2 = op2.n;
int d2 = op2.d;
int n = n1 * n2;
int d = d1 * d2;
int t = fraction::gcd(n, d);
return fraction(n / t, d / t);
}
inline fraction operator * (const fraction& op1, int op2) {
return op1 * fraction(op2, 1);
}
inline fraction operator * (int op1, const fraction& op2) {
return fraction(op1, 1) * op2;
}
inline fraction operator / (const fraction& op1, const fraction& op2)
{
int d2 = op2.d;
if (d2 == 0)
throw zero_div_err("division by zero");
int n2 = op2.n;
return op1 * fraction(d2, n2);
}
inline fraction operator / (const fraction& op1, int op2) {
return op1 / fraction(op2, 1);
}
inline fraction operator / (int op1, const fraction& op2) {
return fraction(op1, 1) / op2;
}
inline std::ostream& operator << (std::ostream& out_file, const fraction& r)
{
if (r.d == 1)
out_file << r.n;
else
out_file << r.n << '/' << r.d;
return (out_file);
}
extern std::istream& operator >> (std::istream& in_file, fraction& r);
#endif /* __fraction_h__ */
fraction.cpp
#include <iostream>
#include "fraction.h"
std::istream& operator >> (std::istream& in_file, fraction& r)
{
int n;
char ch;
int d;
int t;
r = fraction();
std::istream::sentry the_sentry(in_file, true);
if (the_sentry) {
if (in_file.fail()) return (in_file);
in_file >> n;
if (in_file.fail()) return (in_file);
in_file >> ch;
if (in_file.fail()) return (in_file);
if (ch != '/') {
in_file.setstate(std::ios::failbit);
return (in_file);
}
in_file >> d;
if (in_file.fail()) return (in_file);
if (d == 0)
throw zero_div_err("division by zero");
t = fraction::gcd(n, d);
r.n = n / t;
r.d = d / t;
}
else
in_file.setstate(std::ios::failbit);
return (in_file);
}
test_fraction.h
#include <iostream>
#include "fraction.h"
int main(int argc, char *argv[])
{
fraction r1(1, 3);
fraction r2(1, 2);
fraction r3;
std::cout << r1 << " + " << r2 << " = " << r1 + r2 << std::endl;
std::cout << r1 << " - " << r2 << " = " << r1 - r2 << std::endl;
std::cout << r1 << " * " << r2 << " = " << r1 * r2 << std::endl;
std::cout << r1 << " / " << r2 << " = " << r1 / r2 << std::endl;
std::cout << "分数を入力(n/d): ";
try {
std::cin >> r3;
}
catch (zero_div_err& err) {
std::cerr << "ZeroDivisionError: " << err.what << std::endl;
}
catch (...) {
std::cerr << "Error: Unexpected exception occurred" << std::endl;
}
try {
fraction r4(10, 0);
}
catch (zero_div_err& err) {
std::cerr << "ZeroDivisionError: " << err.what << std::endl;
}
catch (...) {
std::cerr << "Error: Unexpected exception occurred" << std::endl;
}
return (0);
}
Makefile
CC=g++
CFLAGS=-g -Wall
all: test_fraction
test_fraction: test_fraction.cpp fraction.o fraction.h
${CC} ${CFLAGS} -o test_fraction test_fraction.cpp fraction.o
fraction.o: fraction.cpp fraction.h
${CC} -c -o fraction.o fraction.cpp
clean:
rm test_fraction
入出力結果(Terminal)
$ make && ./test_fraction g++ -g -Wall -o test_fraction test_fraction.cpp fraction.o 1/3 + 1/2 = 5/6 1/3 - 1/2 = -1/6 1/3 * 1/2 = 1/6 1/3 / 1/2 = 2/3 分数を入力(n/d): 1/0 ZeroDivisionError: division by zero ZeroDivisionError: division by zero $
0 コメント:
コメントを投稿