2014年4月19日土曜日

開発環境

C++実践プログラミング (スティーブ オウアルライン (著)、Steve Oualline (原著)、Steve Oualline(原著)、望月 康司(翻訳)、クイープ(翻訳) 、オライリー・ジャパン)のⅣ部(高度なプログラミング概念)の19章(浮動小数点)、19.11(プログラミング実習)、実習 19-2.を解いてみる。

その他参考書籍

実習 19-2.

コード(BBEdit, Emacs)

fixed_pt.h

#ifndef __fixed_pt_h__
#define __fixed_pt_h__
#include <iostream>

namespace fixed_pt {
  const int fixed_exp = 2;
    
  class fixed_pt {
  private:
    int n;
    int d;
    int i;
  public:
    fixed_pt () {
      n = 0;
      d =1;
      for (i = 0; i < fixed_exp; ++i)
        d *= 10;
    }
    fixed_pt (int m) {
      n = m;
      d =1;
      for (i = 0; i < fixed_exp; ++i)
        d *= 10;
    }
    fixed_pt(double f) {
      d =1;
      for (i = 0; i < fixed_exp; ++i)
        d *= 10;
      n = (int) (f * d);
    }
    // fixed_pt(float f) {
    // }
    // fixed_pt (const fixed_pt& old_fixed_ptr);
    // ~fixed_pt();
    // operator fixed_pt = (const fixed_pt operator);

    fixed_pt operator += (const fixed_pt& op2) {
      return (*this) + op2;
    }
    fixed_pt operator -= (const fixed_pt& op2) {
      return (*this) - op2;
    }
    fixed_pt operator *= (const fixed_pt& op2) {
      return (*this) * op2;
    }
    fixed_pt operator /= (const fixed_pt& op2) {
      return (*this) / op2;
    }

    friend fixed_pt operator + (const fixed_pt& op1, const fixed_pt& op2);
    friend fixed_pt operator - (const fixed_pt& op1, const fixed_pt& op2);
    friend fixed_pt operator * (const fixed_pt& op1, const fixed_pt& op2);
    friend fixed_pt operator / (const fixed_pt& op1, const fixed_pt& op2);
    friend fixed_pt operator - (const fixed_pt& op);
    friend bool operator == (const fixed_pt& op1, const fixed_pt& op2);
    friend bool operator != (const fixed_pt& op1, const fixed_pt& op2);
    friend std::ostream& operator << (std::ostream& out_file,
                                      const fixed_pt& f);
    friend std::istream& operator >> (std::istream& in_file, fixed_pt& f);
  };

  inline fixed_pt operator + (const fixed_pt& op1, const fixed_pt& op2)
  {
    return fixed_pt(op1.n + op2.n);
  }

  inline fixed_pt operator - (const fixed_pt& op1, const fixed_pt& op2)
  {
    return fixed_pt(op1.n - op2.n);
  }

  inline fixed_pt operator * (const fixed_pt& op1, const fixed_pt& op2)
  {
    return fixed_pt(op1.n * op2.n / op1.d);
  }

  inline fixed_pt operator / (const fixed_pt& op1, const fixed_pt& op2)
  {
    double n = (double) op1.n / op2.n * op1.d;
    return fixed_pt((int) n);
  }

  inline fixed_pt operator - (const fixed_pt& op)
  {
    return fixed_pt(-op.n);
  }

  inline bool operator == (const fixed_pt& op1, const fixed_pt& op2)
  {
    return op1.n == op2.n;
  }

  inline bool operator != (const fixed_pt& op1, const fixed_pt& op2)
  {
    return !(op1 == op2);
  }

  extern std::ostream& operator << (std::ostream& out_file, const fixed_pt& f);
  extern std::istream& operator >> (std::istream& in_file, fixed_pt& f);
}
#endif /* __fixed_pt_h__ */

fixed_pt.cpp

#include <iostream>

#include "fixed_pt.h"

namespace fixed_pt{
  std::ostream& operator << (std::ostream& out_file, const fixed_pt& f)
  {
    int before_dp;
    int after_dp[fixed_exp];
    int n;
    int d;
    int i;
    
    n = f.n;
    d = f.d;
    before_dp = n / d;
    n = n < 0 ? -n : n;
    n %= d;
    d /= 10;
    for (i = 0; i < fixed_exp; ++i) {
      after_dp[i] = n / d;
      n %= d;
      d /= 10;
    }
    out_file << before_dp << '.';
    for (i = 0; i < fixed_exp; ++i)
      out_file << after_dp[i];

    return (out_file);
  }
  
  std::istream& operator >> (std::istream& in_file, fixed_pt& f)
  {
    int before_dp;
    char ch;
    int after_dp;
    int d = f.d;
    int i;
    int s;

    f.n = 0;

    std::istream::sentry the_sentry(in_file, true);
    if (the_sentry) {
      if (in_file.fail()) return (in_file);

      in_file >> before_dp;
      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);
      }
      before_dp *= d;
      s = before_dp < 0 ? -1 : 1;

      after_dp = 0;
      d /= 10;
      for (i = 0; i < fixed_exp; ++i) {
        in_file >> ch;
        if (in_file.fail()) return (in_file);
        if (ch < '0' && ch > '9') {
          in_file.setstate(std::ios::failbit);
          return (in_file);
        }
        after_dp += s * static_cast<int>(ch - '0') * d;
        d /= 10;
      }
      f.n = before_dp + after_dp;
    }
    else
      in_file.setstate(std::ios::failbit);
    return (in_file);
  }
}

test_my_float.cpp

#include <iostream>

#include "fixed_pt.h"

int main(int argc, char *argv[])
{
  fixed_pt::fixed_pt f0;
  fixed_pt::fixed_pt f1(1.23);
  fixed_pt::fixed_pt f2(5.6);
  fixed_pt::fixed_pt f3(12345.06);

  std::cout << f0 << "(0.00)" << std::endl;

  std::cout << f1 << "(1.23)" << std::endl;
  std::cout << f2 << "(5.60)" << std::endl;
  std::cout << f3 << "(12345.06)" << std::endl;
  std::cout << "固定小数点数(2桁)を入力 >> ";
  std::cin >> f0;
  std::cout << f0 << 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_fixed_pt

test_fixed_pt: test_fixed_pt.cpp fixed_pt.o
 ${CC} ${CFLAGS} -o test_fixed_pt test_fixed_pt.cpp fixed_pt.o

fixed_pt.o: fixed_pt.cpp fixed_pt.h
 ${CC} -c -o fixed_pt.o fixed_pt.cpp

clean:
 rm test_fixed_pt

入出力結果(Terminal)

$ make && ./test_fixed_pt
g++ -c -o fixed_pt.o fixed_pt.cpp
g++ -g -Wall -o test_fixed_pt test_fixed_pt.cpp fixed_pt.o
0.00(0.00)
1.23(1.23)
5.60(5.60)
12345.06(12345.06)
固定小数点数(2桁)を入力 >> -12.34
-12.34
-12.34 + 1.23 = -11.11
1.23 + -12.34 = -11.11
1.23 + 5.60 = 6.83
5.60 + 1.23 = 6.83
5.60 + 12345.06 = 12350.66
12345.06 + 5.60 = 12350.66
-12.34 - 1.23 = -13.57
1.23 - -12.34 = 13.57
1.23 - 5.60 = -4.37
5.60 - 1.23 = 4.37
5.60 - 12345.06 = -12339.46
12345.06 - 5.60 = 12339.46
-12.34 * 1.23 = -15.17
1.23 * -12.34 = -15.17
1.23 * 5.60 = 6.88
5.60 * 1.23 = 6.88
5.60 * 12345.06 = 69132.33
12345.06 * 5.60 = 69132.33
-12.34 / 1.23 = -10.03
1.23 / -12.34 = 0.09
1.23 / 5.60 = 0.21
5.60 / 1.23 = 4.55
5.60 / 12345.06 = 0.00
12345.06 / 5.60 = 2204.47
$

0 コメント:

コメントを投稿