開発環境
- 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(原著)、望月 康司(翻訳)、クイープ(翻訳) 、オライリー・ジャパン)のⅣ部(高度なプログラミング概念)の19章(浮動小数点)、19.11(プログラミング実習)、実習 19-1.を解いてみる。
その他参考書籍
- C++プログラミング入門 (グレゴリー サティア (著)、ダウグ ブラウン (著)、Gregory Satir (原著)、Doug Brown (原著)、望月 康司 (翻訳)、谷口 功 (翻訳)、オライリージャパン)
実習 19-1.
コード(BBEdit, Emacs)
my_float.h
#ifndef __my_float_h__ #define __my_float_h__ #include <iostream> namespace my_float { class my_float { private: int n; int e; public: my_float () { n = 0; e = 0; } my_float(int n1, int e1 ) { n = n1; e = e1; } /* my_float(const my_float& old_my_float); */ /* ~my_float(); */ /* my_float operator = (const my_float& old_my_float); */ friend my_float operator + (const my_float& op1, const my_float& op2); friend my_float operator - (const my_float& op1, const my_float& op2); friend my_float operator * (const my_float& op1, const my_float& op2); friend my_float operator / (const my_float& op1, const my_float& op2); friend std::ostream& operator << (std::ostream& out_file, const my_float& f); friend std::istream& operator >> (std::istream& in_file, my_float& f); }; inline my_float operator + (const my_float& op1, const my_float& op2) { int op1_n = op1.n; int op1_e = op1.e; int op2_n = op2.n; int op2_e = op2.e; int n; int e; int s; int t; if (op1_e < op2_e) { e = op2_e; for (; op1_e != op2_e; ++op1_e) op1_n /= 10; } else { e = op1_e; for (; op1_e != op2_e; ++op2_e) op2_n /= 10; } n = op1_n + op2_n; if (n < 0) { s = -1; n *= -1; } else s = 1; for (; n >= 100000; ++e) n /= 10; if (n == 0) return my_float(0, 0); for (; n < 10000; --e) n *= 10; t = n % 10; n -= t; n += t >= 5 ? 10 : 0; return my_float(s * n, e); } inline my_float operator - (const my_float& op1, const my_float& op2) { return op1 + my_float(-1 * op2.n, op2.e); } inline my_float operator * (const my_float& op1, const my_float& op2) { int n = op1.n * op2.n; int e = op1.e + op2.e; int s; int t; if (n < 0) { s = -1; n *= -1; } else s = 1; if (n == 0) return my_float(0, 0); for (; n >= 100000; ++e) n /= 10; if (n == 0) return my_float(0, 0); for (; n < 10000; --e) n *= 10; t = n % 10; n -= t; n += t >= 5 ? 10 : 0; return my_float(s * n, e); } inline my_float operator / (const my_float& op1, const my_float& op2) { int n; int e; int s; int t; float f; if (op1.n == 0) return my_float(0, 0); if (op2.n == 0) return my_float(-10000, 0); f = (float) op1.n / op2.n; n = (int) f * 10000; if (n == 0) return my_float(0, 0); if (n < 0) { s = -1; n *= -1; } else s = 1; e = op1.e - op1.e; for (; n >= 100000; ++e) n /= 10; if (n == 0) return my_float(0, 0); for (; n < 10000; --e) n *= 10; t = n % 10; n -= t; n += t >= 5 ? 10 : 0; return my_float(s * n, e); } extern std::ostream& operator << (std::ostream& out_file, const my_float& f); extern std::istream& operator >> (std::istream& in_file, my_float& f); } #endif /*__my_float_h__ */
my_float.cpp
#include <iostream> #include "my_float.h" namespace my_float { std::ostream& operator << (std::ostream& out_file, const my_float& f) { int n; int e; int f1; int f2; int f3; int f4; char s1; char s2; if (f.n >= 0) { s1 = '+'; n = f.n; } else { s1 = '-'; n = -1 * f.n; } if (f.e >= 0) { s2 = '+'; e = f.e; } else { s2 = '-'; e = -1 * f.e; } f1 = n / 10000; n %= 10000; f2 = n / 1000; n %= 1000; f3 = n / 100; n %= 100; f4 = n / 10; n %= 10; f4 += n >= 5 ? 1 : 0; out_file << s1 << f1 << '.' << f2 << f3 << f4 << 'E' << s2 << e; return (out_file); } std::istream& operator >> (std::istream& in_file, my_float& f) { char s1; int f1; int f2; int f3; int f4; char s2; char ch; f.n = 0; f.e = 0; std::istream::sentry the_sentry(in_file, true); if (the_sentry) { if (in_file.fail()) return (in_file); in_file >> s1; if (in_file.fail()) return (in_file); if (s1 != '+' && s1 != '-') { in_file.setstate(std::ios::failbit); return (in_file); } in_file >> ch; if (in_file.fail()) return (in_file); if (ch < '0' && ch > '9') { in_file.setstate(std::ios::failbit); return (in_file); } f1 = static_cast<int>(ch - '0'); in_file >> ch; if (in_file.fail()) return (in_file); if (ch != '.') { in_file.setstate(std::ios::failbit); return (in_file); } in_file >> ch; if (in_file.fail()) return (in_file); if (ch < '0' && ch > '9') { in_file.setstate(std::ios::failbit); return (in_file); } f2 = static_cast<int>(ch - '0'); in_file >> ch; if (in_file.fail()) return (in_file); if (ch < '0' && ch > '9') { in_file.setstate(std::ios::failbit); return (in_file); } f3 = static_cast<int>(ch - '0'); in_file >> ch; if (in_file.fail()) return (in_file); if (ch < '0' && ch > '9') { in_file.setstate(std::ios::failbit); return (in_file); } f4 = static_cast<int>(ch - '0'); in_file >> ch; if (in_file.fail()) return (in_file); if (ch != 'E') { in_file.setstate(std::ios::failbit); return (in_file); } in_file >> s2; if (in_file.fail()) return (in_file); if (s2 != '+' && s2 != '-') { in_file.setstate(std::ios::failbit); return (in_file); } in_file >> ch; if (in_file.fail()) return (in_file); if (ch < '0' && ch > '9') { in_file.setstate(std::ios::failbit); return (in_file); } f.e = static_cast<int>(ch - '0'); f.n = f1 * 10000 + f2 * 1000 + f3 * 100 + f4 * 10; f.n *= s1 == '+' ? 1 : -1; f.e *= s2 == '+' ? 1 : -1; } else in_file.setstate(std::ios::failbit); return (in_file); } }
test_my_float.cpp
#include <iostream> #include "my_float.h" int main(int argc, char *argv[]) { my_float::my_float f0; my_float::my_float f1(-54325,2); my_float::my_float f2(33330, -1); my_float::my_float f3; std::cout << f0 << "(+0.000E+0)" << std::endl; std::cout << f1 << "(-5.433E+2)" << std::endl; std::cout << f2 << "(3.333E-1)" << std::endl; std::cout << "浮動小数点数を入力(±d.dddE±d)>> "; std::cin >> f3; std::cout << f3 << std::endl; std::cout << f0 << " + " << f1 << " = " << f0 + f1 << std::endl; std::cout << f1 << " + " << f0 << " = " << f1 + f0 << std::endl; std::cout << f1 << " + " << f2 << " = " << f1 + f2 << std::endl; std::cout << f2 << " + " << f1 << " = " << f2 + f1 << std::endl; std::cout << f2 << " + " << f3 << " = " << f2 + f3 << std::endl; std::cout << f3 << " + " << f2 << " = " << f3 + f2 << std::endl; std::cout << f0 << " - " << f1 << " = " << f0 - f1 << std::endl; std::cout << f1 << " - " << f0 << " = " << f1 - f0 << std::endl; std::cout << f1 << " - " << f2 << " = " << f1 - f2 << std::endl; std::cout << f2 << " - " << f1 << " = " << f2 - f1 << std::endl; std::cout << f2 << " - " << f3 << " = " << f2 - f3 << std::endl; std::cout << f3 << " - " << f2 << " = " << f3 - f2 << std::endl; std::cout << f0 << " * " << f1 << " = " << f0 * f1 << std::endl; std::cout << f1 << " * " << f0 << " = " << f1 * f0 << std::endl; std::cout << f1 << " * " << f2 << " = " << f1 * f2 << std::endl; std::cout << f2 << " * " << f1 << " = " << f2 * f1 << std::endl; std::cout << f2 << " * " << f3 << " = " << f2 * f3 << std::endl; std::cout << f3 << " * " << f2 << " = " << f3 * f2 << std::endl; std::cout << f0 << " / " << f1 << " = " << f0 / f1 << std::endl; std::cout << f1 << " / " << f0 << " = " << f1 / f0 << std::endl; std::cout << f1 << " / " << f2 << " = " << f1 / f2 << std::endl; std::cout << f2 << " / " << f1 << " = " << f2 / f1 << std::endl; std::cout << f2 << " / " << f3 << " = " << f2 / f3 << std::endl; std::cout << f3 << " / " << f2 << " = " << f3 / f2 << std::endl; return (0); }
Makefile
CC=g++ CFLAGS=-g -Wall all: test_my_float test_my_float: test_my_float.cpp my_float.o ${CC} ${CFLAGS} -o test_my_float test_my_float.cpp my_float.o my_float.o: my_float.cpp my_float.h ${CC} -c -o my_float.o my_float.cpp clean: rm test_my_float
入出力結果(Terminal)
$ make && ./test_my_float g++ -c -o my_float.o my_float.cpp g++ -g -Wall -o test_my_float test_my_float.cpp my_float.o +0.000E+0(+0.000E+0) -5.433E+2(-5.433E+2) +3.333E-1(3.333E-1) 浮動小数点数を入力(±d.dddE±d)>> +3.333E-1 +3.333E-1 +0.000E+0 + -5.433E+2 = -5.433E+2 -5.433E+2 + +0.000E+0 = -5.433E+2 -5.433E+2 + +3.333E-1 = -5.429E+2 +3.333E-1 + -5.433E+2 = -5.429E+2 +3.333E-1 + +3.333E-1 = +6.666E-1 +3.333E-1 + +3.333E-1 = +6.666E-1 +0.000E+0 - -5.433E+2 = +5.433E+2 -5.433E+2 - +0.000E+0 = -5.433E+2 -5.433E+2 - +3.333E-1 = -5.436E+2 +3.333E-1 - -5.433E+2 = +5.436E+2 +3.333E-1 - +3.333E-1 = +0.000E+0 +3.333E-1 - +3.333E-1 = +0.000E+0 +0.000E+0 * -5.433E+2 = +0.000E+0 -5.433E+2 * +0.000E+0 = +0.000E+0 -5.433E+2 * +3.333E-1 = -1.811E+6 +3.333E-1 * -5.433E+2 = -1.811E+6 +3.333E-1 * +3.333E-1 = +1.111E+3 +3.333E-1 * +3.333E-1 = +1.111E+3 +0.000E+0 / -5.433E+2 = +0.000E+0 -5.433E+2 / +0.000E+0 = -1.000E+0 -5.433E+2 / +3.333E-1 = -1.000E+0 +3.333E-1 / -5.433E+2 = +0.000E+0 +3.333E-1 / +3.333E-1 = +1.000E+0 +3.333E-1 / +3.333E-1 = +1.000E+0 $
0 コメント:
コメントを投稿