다음은 행렬 곱셈을 수행하는 C++ 언어 소스이다.

행의 수, 열의 수. 그리고 두 행렬의 요소들을 모두 컨솔에서 입력해야 한다.

소스는 http://www.physics.utah.edu/~detar/lessons/c++/matrices/node4.html 의 것을 다소 수정한 것이다.

 

// Filename: testSomeMat-03.cpp
//
// Copmpile: cl /EHsc testSomeMat-03.cpp
// Execute: testSomeMat-03
//
// Date: 2003.9. 20.

#include <iostream>
#include <vector>
#include <iomanip>
 
using namespace std;

typedef vector<double> Vec;
typedef vector<Vec> Mat;

Vec operator*(const Mat &a, const Vec &x){
  int i,j;
  int m = a.size();
  int n = x.size();

  Vec prod(m);

  for(i = 0; i < m; i++){
    prod[i] = 0.;
    for(j = 0; j < n; j++)
      prod[i] += a[i][j]*x[j];
  }
  return prod;
}

Mat operator*(const Mat &a, const Mat &b) {
  int i, j, k;
  int m = a.size();
  int n = a[0].size();
  int p = b[0].size();

  Mat c;

  for(i = 0; i < m; i++){
    Vec row(p);
    for(j = 0; j < p; j++) {
      row[j] = 0.;
      for(k = 0; k < n; k++) {
          row[j] += a[i][k]*b[k][j];
      }
    }
    c.push_back(row);
  }
  return c;
}

void printMatrix(const Mat &a, int width) {
  int i, j;
  int m = a.size();
  int n = a[0].size();

  for(i = 0; i < m; i++) {
     if (i == 0)
        cout << "  [[";
     else
        cout << "   [";
      for(j = 0; j < n; j++) {
        cout << "  " << setw(width) << a[i][j];
      }
     if (i < m - 1)
          cout << "  ]";
     else
          cout << "  ]]";
      cout << "\n";
  }
}

int main() {

  int i, j, k, m, n, p;

  cout << "첫째 행렬의 행의 수: ";
  cin >> m;
  cout << "첫째 행렬의 열의 수: ";
  cin >> n;
  cout << "둘째 행렬의 열의 수: ";
  cin >> p;

  cout << "\n";
  
  // 첫째 행렬과 이 행렬의 입력을 위한 벡터 선언
  Mat a;
  Vec row(n);

  cout << "첫째 행렬의 요소들을 입력하시오.\n";
  for(i = 0; i < m; i++){
    for(j = 0; j < n; j++)cin >> row[j];
    a.push_back(row);
  }

  // 둘째 행렬과 이 행렬의 입력을 위한 벡터 선언
  Mat b;
  Vec row2(p);

  cout << "둘째 행렬의 요소들을 입력하시오.\n";
  for(i = 0; i < n; i++){
    for(j = 0; j < p; j++)cin >> row2[j];
    b.push_back(row2);
  }


  Mat c = a*b;

  cout << "\nA = \n";
  printMatrix(a, 8);

  cout << "\nB = \n";
  printMatrix(b, 8);

  cout << "\nA*B = \n";
  printMatrix(c, 8);

  return 0;
}

/*
Output:
첫째 행렬의 행의 수: 3
첫째 행렬의 열의 수: 3
둘째 행렬의 열의 수: 1

첫째 행렬의 요소들을 입력하시오.
 2  5 6
1 2 0
9 7 1
둘째 행렬의 요소들을 입력하시오.
4 1 2

A =
  [[         2         5         6  ]
   [         1         2         0  ]
   [         9         7         1  ]]

B =
  [[         4  ]
   [         1  ]
   [         2  ]]

A*B =
  [[        25  ]
   [         6  ]
   [        45  ]]
*/

 

 

다음은 정사각행렬의 행렬식을 구하는 소스이다.

// Filename: determinant-04.cpp
//
// Compile: g++ -std=c++11 -o determinant-04 determinant-04.cpp
// Execute: ./determinant-04
//
//     or
//
// Compile: cl /EHsc determinant-04.cpp
// Execute: determinant-04
//
// Date: 2013. 9. 20.

#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <iomanip>
#include <cstring>

using namespace std;

typedef vector<double> Vec;
typedef vector<Vec> Mat;

Vec operator*(const Mat &a, const Vec &x){
  int i,j;
  int m = a.size();
  int n = x.size();

  Vec prod(m);

  for(i = 0; i < m; i++){
    prod[i] = 0.;
    for(j = 0; j < n; j++)
      prod[i] += a[i][j]*x[j];
  }
  return prod;
}

Mat operator*(const Mat &a, const Mat &b) {
  int i, j, k;
  int m = a.size();
  int n = a[0].size();
  int p = b[0].size();

  Mat c;

  for(i = 0; i < m; i++){
    Vec row(p);
    for(j = 0; j < p; j++) {
      row[j] = 0.;
      for(k = 0; k < n; k++) {
          row[j] += a[i][k]*b[k][j];
      }
    }
    c.push_back(row);
  }
  return c;
}

void printMatrix(const Mat &a, int width) {
  int i, j;
  int m = a.size();
  int n = a[0].size();

  for(i = 0; i < m; i++) {
     if (i == 0)
        cout << "  [[";
     else
        cout << "   [";
      for(j = 0; j < n; j++) {
        cout << "  " << setw(width) << a[i][j];
      }
     if (i < m - 1)
          cout << "  ]";
     else
          cout << "  ]]";
      cout << "\n";
  }
}

void printPermutation(const vector<int> pmt, int counter)
{
    int n = pmt.size();
    cout << "[";
    if (n > 0)
    {
        cout << " " << pmt[0];
        if (n > 1)
        {
            for (int i = 1; i < n; i++)
            {
                cout << ", " << pmt[i];
            }
        }
        cout << " ";
    }
    cout << "]";
    if ((counter % 2) == 0)
        cout << "    -- even --";
    else
        cout << "    -- odd  --";
    cout << endl;
}

void swap(vector<int> &pmt, int i, int j)
{
    int x = pmt[j];
    pmt[j] = pmt[i];
    pmt[i] = x;
}


 

void doPermute(const Mat &mat, int dim, vector<int> pmt, int size, int &cnt, double &det, bool show_flag)
{
    double x;
    double y;
    if (size == 2)
    {
       if (show_flag)
            printPermutation(pmt, cnt);
        x = 1.0;
        for (int j = 0; j < dim; j++)
        {
         if (mat[j][pmt[j]] == 0) {
          x = 0;
          break;
         }
         x *= mat[j][pmt[j]];
        }
        det += ((cnt % 2) == 0) ? x : -x;
        swap(pmt, 0, 1);
        cnt++;
        if (show_flag)
            printPermutation(pmt, cnt);
        x = 1.0;
        for (int j = 0; j < dim; j++)
        {
           if (mat[j][pmt[j]] == 0) {
          x = 0.0;
          break;
         }
        x *= mat[j][pmt[j]];
        }
        det += ((cnt % 2) == 0) ? x : -x;
        swap(pmt, 0, 1);
        cnt--;
    }
    else if (size > 2)
    {
        doPermute(mat, dim, pmt, size - 1, cnt, det, show_flag);
        for (int i = size - 2; i >= 0; i--)
        {
             swap(pmt, i, size - 1);
             cnt++;
             doPermute(mat, dim, pmt, size - 1, cnt, det, show_flag);
        }
        for (int i = 0; i <= size - 2; i++)
        {
            swap(pmt, i, size - 1);
            cnt--;
        }
    }
}

int main(int argc, const char *argv[])
{
    // vector<int> v = { 0, 1, 2, 3, 4 };     // syntax for C++11
    vector<int> v(5);
    for (int i = 0; i < 5; i++)
    {
     v[i] = i;
    }
   
    int counter = 0;
    int dim = 3;
    int n = 3;
    double d = 0.0;
    
    cout << "정사각행렬의 행의 수: ";
    cin >> n;

     // Allocate space for the vectors
     Mat a;
     Vec row(n);

     cout << "행렬의 모든 요소를 입력하시오.\n";
     for (int i = 0; i < n; i++) {
         for (int j = 0; j < n; j++) {
             cin >> row[j];
         }
         a.push_back(row);
     }

     cout << "\nA = \n";
     printMatrix(a, 8);


    if (n > 5)
    {
        for (int i = 5; i < n; i++)
        {
            v.push_back(i);
        }
    }
    else if (n < 5) {
       for (int i = 0; i < 5 - n; i++)
       {
          v.pop_back();
       }
    }

    dim = n;


    cout << endl;
    
    bool show_flag = false;    // true;    // false;
    doPermute(a, dim, v, n, counter, d, show_flag);

    if (show_flag)
        cout << endl;
    cout << "A의 행렬식: det(A) = " << d << endl;
    return 0;
}

/*
Execute & Output:
정사각행렬의 행의 수: 2
행렬의 모든 요소를 입력하시오.
7 8
9 2

A =
  [[         7         8  ]
   [         9         2  ]]

A의 행렬식: det(A) = -58
*/

 

 

Posted by Scripter
,

정리 (정사각행렬의 행렬식, derterminant)

n × n 행렬 A = \big( a_{ij} \big) 의 행렬식 \det(A) 는 다음 식과 같다

         \det(A) \ = \ \sum_{\sigma} \, \textrm{sign}(\sigma) \, a_{1 \sigma(1)} a_{2 \sigma(2)} \cdots a_{n \sigma(n)}

위에서 합은 집합 \{ 1, 2, \cdots, n \} 위에서의 모든 순열 \sigma에 관한 합이며, \textrm{sign}(\sigma)\sigma가 우순열인 경우에는 +1이고, 기순열인 경우에는 -1이다.

 

다음의 C++ 언어로 작성된 소스는 순열을 출력하는 소스를 수정아여 정사각행렬의 행렬식을 계산하도록 하였다.

컴파일은 g++ 또는 Visual C++ 의 명령줄 컴파일러 cl 을 이용한다.

 

// Filename: determinant-03.cpp
//
// Compile: g++ -std=c++11 -o determinant-03 determinant-03.cpp
// Execute: ./determinant-03 [integer]
//
//     or
//
// Compile: cl /EHsc determinant-03.cpp
// Execute: determinant-03 [integer]
//
// Date: 2013. 9. 20.

#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <iomanip>
#include <cstring>

using namespace std;

template<typename T>
class Array2D
{
    private:
        const int width;
        T * data;
    public:
        T& operator() (int x, int y) { return data[y*width + x]; }
        Array2D(const int w, const int h) : width(w) { data = new T[w*h]; }
        ~Array2D() { delete [] data; }
};

void printPermutation(const vector<int> pmt, int counter)
{
    int n = pmt.size();
    cout << "[";
    if (n > 0)
    {
        cout << " " << pmt[0];
        if (n > 1)
        {
            for (int i = 1; i < n; i++)
            {
                cout << ", " << pmt[i];
            }
        }
        cout << " ";
    }
    cout << "]";
    if ((counter % 2) == 0)
        cout << "    -- even --";
    else
        cout << "    -- odd  --";
    cout << endl;
}

void swap(vector<int> &pmt, int i, int j)
{
    int x = pmt[j];
    pmt[j] = pmt[i];
    pmt[i] = x;
}

void printMatrix(Array2D<double> &mat, int nrow, int ncol)
{
    for (int i = 0; i < nrow; i++)
    {
        cout << "[[";
        for (int j = 0; j < ncol; j++)
        {
            cout << " " << setw(9) << mat(i, j) << " ";
        }
        cout << "  ]]" << endl;
    }
    cout << endl;
}

#include <sstream>
void readMatrix(Array2D<double> &mat, int nrow, int ncol)
{
  std::string line;
     double x;
     int i = 0;
     while (i < nrow*ncol)
     {
          cin >> line;
          std::istringstream iss(line);
          while (iss)
          {
              std::string sub;
              iss >> sub;

              std::istringstream ins(sub);
              if (!(ins >> x))
                  break;
              mat(i / ncol, i % ncol) = x;
              i++;
          }
     }
}

void doPermute(Array2D<double> &mat, int dim, vector<int> pmt, int size, int &cnt, double &det, bool show_flag)
{
    double x;
    double y;
    if (size == 2)
    {
       if (show_flag)
            printPermutation(pmt, cnt);
        x = 1.0;
        for (int j = 0; j < dim; j++)
        {
         if (mat(j, pmt[j]) == 0) {
          x = 0;
          break;
         }
         x *= mat(j, pmt[j]);
        }
        det += ((cnt % 2) == 0) ? x : -x;
        swap(pmt, 0, 1);
        cnt++;
        if (show_flag)
            printPermutation(pmt, cnt);
        x = 1.0;
        for (int j = 0; j < dim; j++)
        {
           if (mat(j, pmt[j]) == 0) {
          x = 0.0;
          break;
         }
        x *= mat(j, pmt[j]);
        }
        det += ((cnt % 2) == 0) ? x : -x;
        swap(pmt, 0, 1);
        cnt--;
    }
    else if (size > 2)
    {
        doPermute(mat, dim, pmt, size - 1, cnt, det, show_flag);
        for (int i = size - 2; i >= 0; i--)
        {
             swap(pmt, i, size - 1);
             cnt++;
             doPermute(mat, dim, pmt, size - 1, cnt, det, show_flag);
        }
        for (int i = 0; i <= size - 2; i++)
        {
            swap(pmt, i, size - 1);
            cnt--;
        }
    }
}

int main(int argc, const char *argv[])
{
    // vector<int> v = { 0, 1, 2, 3, 4 };     // syntax for C++11
    vector<int> v(5);
    for (int i = 0; i < 5; i++)
    {
     v[i] = i;
    }
   
    int counter = 0;
    int dim = 3;
    int k = 3;
    double d = 0.0;


    if (argc > 1)
    {
        sscanf(argv[1], "%d", &k);
    }

    if (k > 5)
    {
        for (int i = 5; i < k; i++)
        {
            v.push_back(i);
        }
    }
    else if (k < 5) {
       for (int i = 0; i < 5 - k; i++)
       {
          v.pop_back();
       }
    }

    dim = k;
    Array2D<double> mat(dim, dim);

    cout << "Input a " << k << " by " << k << " matrix" << endl;

    readMatrix(mat, k, k);

    cout << endl;
    cout << "The given matrix is " << endl;
    printMatrix(mat, dim, dim);
   
    bool show_flag = false;
    doPermute(mat, dim, v, k, counter, d, show_flag);

    if (show_flag)
        cout << endl;
    cout << "Its determinant is " << d << "." << endl;
    return 0;
}

/*
Execute & Output:
명령프롬프트> determinant-03
Input a 3 by 3 matrix
1 2 3   4 5 6.02   7 8.1   9

The given matrix is
[[         1          2          3   ]]
[[         4          5       6.02   ]]
[[         7        8.1          9   ]]

Its determinant is 0.718.

명령프롬프트> determinant-03 2
Input a 2 by 2 matrix
7 8
0.1 5.1

The given matrix is
[[         7          8   ]]
[[       0.1        5.1   ]]

Its determinant is 34.9.

명령프롬프트> determinant-03 4
Input a 4 by 4 matrix
1 2 3   4 5 6.02   7 8.1   9
0 0 0 7 0 2 3

The given matrix is
[[         1          2          3          4   ]]
[[         5       6.02          7        8.1   ]]
[[         9          0          0          0   ]]
[[         7          0          2          3   ]]

Its determinant is 32.22.
*/

 

 

 

Posted by Scripter
,

정의  (순열(또는 치환), permutation)

S가 집합일 때, S에서 S 위로 가는 일대일함수 즉, S에서 S로 가는 전단사함수를 집합 S 위에서의 순열이라고 한다, 특히 S가 원소 n개를 갖는 유한집합인 경우 S 위에서의 서로 다른 순열은 총 n!(n 팩토리얼)개이다.

 

다음의 C++ 언어로 작성된 소스는 유한집합 S = { 0, 1, 2, ... , n - 1 } 상에서의 모든 순열을 컨솔에 출력해준다. 우순열(even permutation)인지 기순열(odd permutation)인지도 판별해준다.

컴파일은 g++ 또는 Visual C++ 의 명령줄 컴파일러 cl 을 이용한다.

 

// Filename: permutations.cpp
//
// Compile: g++ -std=c++11 -o permutations permutations.cpp
// Execute: ./permutations [integer]
//
//     or
//
// Compile: cl /EHsc permutations.cpp
// Execute: permutations [integer]
//
// Date: 2013. 9. 20.

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

void printVector(const vector<int> v, int counter)
{
    int n = v.size();
    cout << "[";
    if (n > 0)
    {
        cout << " " << v[0];
        if (n > 1)
        {
            for (int i = 1; i < n; i++)
            {
                cout << ", " << v[i];
            }
        }
        cout << " ";
    }
    cout << "]";
    if ((counter % 2) == 0)
        cout << "    -- even --";
    else
        cout << "    -- odd  --";
    cout << endl;
}

void swap(vector<int> &v, int i, int j)
{
    int x = v[j];
    v[j] = v[i];
    v[i] = x;
}

void doPermute(vector<int> v, int size, int &cnt)
{
    if (size == 2)
    {
        printVector(v, cnt);
        swap(v, 0, 1);
        cnt++;
        printVector(v, cnt);
        swap(v, 0, 1);
        cnt--;
    }
    else if (size > 2)
    {
        doPermute(v, size - 1, cnt);
        for (int i = size - 2; i >= 0; i--)
        {
            swap(v, i, size - 1);
            cnt++;
            doPermute(v, size - 1, cnt);
        }
        for (int i = 0; i <= size - 2; i++)
        {
            swap(v, i, size - 1);
            cnt--;
        }
    }
}

int main(int argc, const char *argv[])
{
    // vector<int> v = { 0, 1, 2, 3, 4 };     // syntax  for c++11
    vector<int> v(5);
    for (int i = 0; i < 5; i++)
    {
        v[i] = i;
    }

    int counter = 0;
    int k = 3;

    if (argc > 1)
    {
        sscanf(argv[1], "%d", &k);
    }

    if (k > 5)
    {
        for (int i = 6; i <= k; i++)
        {
            v.push_back(i);
        }
    }
    else if (k < 5) {
       for (int i = 0; i < 5 - k; i++)
       {
          v.pop_back();
       }
    }

    doPermute(v, k, counter);

    return 0;
}

/*
Execute & Output:

$ ./permutations
[ 0, 1, 2 ]    -- even --
[ 1, 0, 2 ]    -- odd  --
[ 0, 2, 1 ]    -- odd  --
[ 2, 0, 1 ]    -- even --
[ 1, 2, 0 ]    -- even --
[ 2, 1, 0 ]    -- odd  --


$ ./permutations 2
[ 0, 1 ]    -- even --
[ 1, 0 ]    -- odd  --


$ ./permutations 4
[ 0, 1, 2, 3 ]    -- even --
[ 1, 0, 2, 3 ]    -- odd  --
[ 0, 2, 1, 3 ]    -- odd  --
[ 2, 0, 1, 3 ]    -- even --
[ 1, 2, 0, 3 ]    -- even --
[ 2, 1, 0, 3 ]    -- odd  --
[ 0, 1, 3, 2 ]    -- odd  --
[ 1, 0, 3, 2 ]    -- even --
[ 0, 3, 1, 2 ]    -- even --
[ 3, 0, 1, 2 ]    -- odd  --
[ 1, 3, 0, 2 ]    -- odd  --
[ 3, 1, 0, 2 ]    -- even --
[ 0, 2, 3, 1 ]    -- even --
[ 2, 0, 3, 1 ]    -- odd  --
[ 0, 3, 2, 1 ]    -- odd  --
[ 3, 0, 2, 1 ]    -- even --
[ 2, 3, 0, 1 ]    -- even --
[ 3, 2, 0, 1 ]    -- odd  --
[ 1, 2, 3, 0 ]    -- odd  --
[ 2, 1, 3, 0 ]    -- even --
[ 1, 3, 2, 0 ]    -- even --
[ 3, 1, 2, 0 ]    -- odd  --
[ 2, 3, 1, 0 ]    -- odd  --
[ 3, 2, 1, 0 ]    -- even --
*/

 

 

Posted by Scripter
,

 

C++ 언어 소스:

// Filename: testHexView02.cpp
//
//  Chapter 1.  Section 1.
//
//       A basic pattern of C++ Programing
//
// Compile: cl /EHsc testHexView02.cpp
// Compile: g++ -std=c++11 -o testHexView02 testHexView02.cpp
// Compile: g++ -std=c++0x -o testHexView02 testHexView02.cpp


#include <iostream>
#include <fstream>
#include <string.h>

using namespace std;

void toHex(char c, char a[3]);
void toHex4(int n, char a[5]);
void toHex8(int n, char a[10]);

int main(int argc, char *argv[])
{
     if (argc < 2)
    {
        cout << "Usage: testHexView02 [filename]" << endl;
        exit( 1 );
    }

    const char *fname = argv[1];
    
    ifstream in(fname,ios::in | ios::binary | ios::ate);
 
    if (!in)
    {
        cout << "Fail to open the file: \"" << fname << ":\"." << endl;
        exit( 1 );
    }

    ifstream::pos_type fsize;

    char s[3];
    char t[10];
    char buf[16];
    fpos_t n = 0L;

    s[2] = '\0';
    t[4] = ' ';
    t[9] = '\0';
    if (in.is_open())
    {
        fsize = in.tellg();
        cout << "Its file size is " << fsize << "." << endl << endl;

        in.seekg (0, ios::beg);

        while (n < fsize && !in.eof())
        {
            toHex8(n, t);
            cout << t <<": ";
      
            in.read(buf, sizeof(buf));
            char x;
            long m = (((fsize - n) < 16L) ? (long) (fsize - n) : 16L);
            for (int i = 0; i < m; i++)
            {
                x = buf[i];
                toHex(x, s);
                cout << s;
                if (i == 7)
                    cout << "-";
                else
                    cout << " ";
            }
            if (m < 16)
            {
                for (int i = 0; i < 16 - m; i++)
                {
                    cout << "   ";
                }
            }

            cout << "|";
            for (int i = 0; i < m; i++)
            {
                if (buf[i] < ' ')
                    cout << ".";
                else
                    cout << buf[i];
            }

            if (m < 16)
            {
                for (int i = 0; i < 16 - m; i++)
                {
                    cout << " ";
                }
            }
            cout << "|";

            n += m;
            cout << endl;
        }

        in.close();
     
        cout << endl;
        cout << "Read " << n << " bytes" << endl;
    }
    else {
        cout << "Fail to read the file: \"" << fname << "\"." << endl;
    }

}

void toHex(char c, char a[3]) {
    int x1, x2;
    x1 = (c & 0xF0) >> 4;
    x2 = c & 0x0F;
    if (x1 < 10)
        a[0] = x1 + '0';
    else
        a[0] = (x1 - 10) + 'A';
    if (x2 < 10)
        a[1] = x2 + '0';
    else
        a[1] = (x2 - 10) + 'A';
}

void toHex4(int n, char a[5]) {
     int x1, x2, x3, x4;
    x1 = (n & 0xF000) >> 12;
    x2 = (n & 0xF00) >> 8;
    x3 = (n & 0xF0) >> 4;
    x4 = n & 0x0F;
    if (x1 < 10)
        a[0] = x1 + '0';
    else
        a[0] = (x1 - 10) + 'A';
    if (x2 < 10)
        a[1] = x2 + '0';
    else
        a[1] = (x2 - 10) + 'A';
    if (x3 < 10)
        a[2] = x3 + '0';
    else
        a[2] = (x3 - 10) + 'A';
    if (x4 < 10)
        a[3] = x4 + '0';
    else
        a[3] = (x4 - 10) + 'A';
}

void toHex8(int n, char a[10]) {
    int x1, x2, x3, x4, x5, x6, x7, x8;
    x1 = (n & 0xF0000000) >> 28;
    x2 = (n & 0xF000000) >> 24;
    x3 = (n & 0xF00000) >> 20;
    x4 = (n & 0xF0000) >> 16;
    x5 = (n & 0xF000) >> 12;
    x6 = (n & 0xF00) >> 8;
    x7 = (n & 0xF0) >> 4;
    x8 = n & 0x0F;
    if (x1 < 10)
        a[0] = x1 + '0';
    else
        a[0] = (x1 - 10) + 'A';
    if (x2 < 10)
        a[1] = x2 + '0';
    else
        a[1] = (x2 - 10) + 'A';
    if (x3 < 10)
        a[2] = x3 + '0';
    else
        a[2] = (x3 - 10) + 'A';
    if (x4 < 10)
        a[3] = x4 + '0';
    else
        a[3] = (x4 - 10) + 'A';
    a[4] = ' ';
    if (x5 < 10)
        a[5] = x5 + '0';
    else
        a[5] = (x5 - 10) + 'A';
    if (x6 < 10)
        a[6] = x6 + '0';
    else
        a[6] = (x6 - 10) + 'A';
    if (x7 < 10)
        a[7] = x7 + '0';
    else
        a[7] = (x7 - 10) + 'A';
    if (x8 < 10)
        a[8] = x8 + '0';
    else
        a[8] = (x8 - 10) + 'A';
}

 

 

명령창에서 Visual C++로 컴파일하기> cl /EHsc testHexView02.cpp


 

MinGW의 g++로 컴파일하기 위해 PATH를 설장하는 일괄파일(bat 파일)의 내용:

set path=d:\MinGW480\bin;d:\MinGW480\MSYS\1.0\bin;%path%

 

MinGW애서 컴파일하기> g++ -std=c++11 -o testHexView02 testHexView02.cpp

 

실행 예 1> testHexView02 temp_1.bin
Its file size is 12.

0000 0000: 48 65 6C 6C 6F 20 74 68-65 72 65 0A             |Hello there.    |

Read 12 bytes

 

실행 예 2> testHexView02 example.bin
Its file size is 21.

0000 0000: 41 01 00 00 00 42 29 40-00 02 00 00 00 43 00 00 |A....B)@.....C..|
0000 0010: 00 03 00 00 00                                  |.....           |

Read 21 bytes

 

 

Posted by Scripter
,

음이 아닌 실수 A 의 평방근 sqrt(A) 를 구하는 Heron 의 방법:

        반복함수  g(x) = (x + A/x) / 2   를 이용

 

실수 A 의 n제곱근 root(n, A) 를 구하는 Newton-Raphson 의 방법

        반복함수  g(x) = ((n-1)*x + A/(x**(n - 1))) / n    를 이용

n = 2 인 경우에는 Newton-Raphson 의 방법이 Heron 의 방법과 동일하다.

(참조. http://en.wikipedia.org/wiki/Newton's_method )

 

C 언어와 C++ 언어에는 (math.h 를 인클루드하여 사용하는) 표준 수학 라이브러리에 지수 계산 함수 pow() 가 이미 구현되어 있다. 하지만 차후 필요한 데가 있을 것 같아서 이와 유사한 n 제곱 함수와 n 제곱근 함수를 구현해 보았다.

지수가 정수인 거듭제곱을 계산하는  함수도 nPow(), gPow, mPow() 세 개 구현해 놓았는데, 이들 세 함수는 절차적 언어의 성능상 재귀호출이 아니고 단순 반복 기법을 사용하는 함수이다. 이 세 함수 중 mPow() 의 성능이 가장 우수하다. 큰 지수의 경우 for 반복문의 반복회수를 따져 보면 성능 비교를 할 수 있을 것이다. (성능 비교를 위해 세 가지를 모두 소스에 남겨 두었다.) mPow() 함수는 n 제곱근을 구하는 재귀함수 newtonNthRoot(int, double) 의 구현에 사용되기도 한다. if ... else ... 구문이 많아 소스가 복잡하게 보일지 모르겠으나 이는 밑수나 지수가 음수이거나 0인 경우의 처리를 위함이다. 구현된 모든 함수의 구현에는 예외상황(예를 들어, 음수의 짝수 제곱근 같은 예외상황) 처리 과정이 있다.

아래의 소스는 Visual C++ 외에 g++ 로 컴파일해도 수정 없이 잘 되리라고 본다.

예외상황 처리 때문에, Visual C++ 로 컴파일 할 때는 /EHsc 옵션을 붙여 주어야 하고, g++ 로 컴파일할 때는 -fexceptions 옵션을 반드시 붙여 주어야 한다.

// Filename: testNthRoot.cpp
//
//            Approximate square roots, cubic roots and n-th roots of a given number.
//
// Compile: cl /EHsc testNthRoot.cpp
// Execute: testNthRoot
//
//  Or
//
// Compile:  g++ -o testNthRoot testNthRoot.cpp -fexceptions
// Execute: ./testNthRoot
//
// Date: 2013. 1. 6.
// Copyright (c) 2013 PH Kim  (pkim __AT__ scripts.pe.kr)

#include <stdio.h>
#include <iostream>
#include <cmath>
#include <cstring>
// #include <memory.h>
#include <exception>

using namespace std;

class CalcException: public exception
{
  virtual const char* what() const throw()
  {
    return "Not supported calculation exception";
  }
} cannotCalcEx;

class NotDefinedException: public exception
{
  virtual const char* what() const throw()
  {
    return "Not defined calculation exception";
  }
} notDefinedEx;

class MayInaccurateException: public exception
{
  virtual const char* what() const throw()
  {
    return "Inaccurate approximation by too many iterrations.";
  }
} inaccurateApproxEx;

 

#define MAX_ITER 20000
#define M_EPSILON 1.0e-15


/**
  * Compute the n-th root of x to a given scale, x > 0.
  */
double nPow(double a, int n)
{
    if (n > 0) {
        if (n == 1)
            return a;
        else {
            if (a == 0.0 || a == 1.0) {
                return a;
            }
            else if (a == -1.0) {
                if (n % 2 == 1)
                    return -1.0;
                else
                    return 1.0;
            }
            else if (a < 0.0) {
                if (n % 2 == 1)
                    return -nPow(-a, n);
                else
                    return nPow(-a, n);
            }
            else {
                double y = 1.0;
                for (int i = 0; i < n; i++) {
                    y *= a;
                }
                return y;
            }
        }
    }
    else if (n == 0) {
        return 1.0;
    }
    else {      //  when n < 0
        if (a == 0.0)
            // throw "Negative powering exception of zero.";
            throw cannotCalcEx;
        else {
            if (n == -1)
                return 1.0/a;
            else
                return 1.0/nPow(a, -n);
        }
    }
}

 

/**
  * Compute the n-th root of x to a given scale, x > 0.
  */
double gPow(double a, int n)
{
    if (n > 0) {
        if (n == 1)
            return a;
        else {
            if (a == 0.0 || a == 1.0) {
                return a;
            }
            else if (a == -1.0) {
                if (n % 2 == 1)
                    return -1.0;
                else
                    return 1.0;
            }
            else if (a < 0.0) {
                if (n % 2 == 1)
                    return -gPow(-a, n);
                else
                    return gPow(-a, n);
            }
            else {


                double y = 1.0;
                double r = a;
                int m = 8*sizeof(int) - 1;   // ignore the most significant bit which means the +/- sign.
                int one = 1;
                for (int i = 0; i < m; i++) {
                    if ((n & one) == 0) {
                        y *= 1.0;
                    }
                    else {
                        y *= r;
                    }
                    r = r*r;
                    one <<= 1;
                    if (one > n)
                        break;
                }
                return y;
            }
        }
    }
    else if (n == 0) {
        return 1.0;
    }
    else {      //  when n < 0
        if (a == 0.0)
            // throw "Negative powering exception of zero.";
            throw cannotCalcEx;
        else {
            if (n == -1)
                return 1.0/a;
            else
                return 1.0/gPow(a, -n);
        }
    }
}

 

/**
  * Compute the n-th root of x to a given scale, x > 0.
  */
double mPow(double a, int n)
{
    if (n > 0) {
        if (n == 1)
            return a;
        else {
            if (a == 0.0 || a == 1.0) {
                return a;
            }
            else if (a == -1.0) {
                if (n % 2 == 1)
                    return -1.0;
                else
                    return 1.0;
            }
            else if (a < 0.0) {
                if (n % 2 == 1)
                    return -mPow(-a, n);
                else
                    return mPow(-a, n);
            }
            else {


                double y = 1.0;
                double r = a;
                int m = n;
                while (m > 0) {
                    if ((m & 0x1) != 0) {
                        y *= r;
                    }
                    r = r*r;
                    m >>= 1;
                }
                return y;
            }
        }
    }
    else if (n == 0) {
        return 1.0;
    }
    else {      //  when n < 0
        if (a == 0.0)
            // throw "Negative powering exception of zero.";
            throw cannotCalcEx;
        else {
            if (n == -1)
                return 1.0/a;
            else
                return 1.0/mPow(a, -n);
        }
    }
}

 

/**
  * Compute the square root of x to a given scale, x > 0.
  */
double heronSqrt(double a)
{
    if (a < 0.0) {
        // throw "Cannot find the sqrt of a negative number.";
        throw notDefinedEx;
    }
    else if (a == 0.0 || a == 1.0) {
        return a;
    }
    else {
        double x1 = a;
        double x2 = (x1 + a/x1)/2.0;
        double er = x1 - x2;
        int counter = 0;
        while (x1 + er != x1) {
            x1 = x2;
            x2 = (x1 + a/x1)/2.0;
            er = x1 - x2;
            if (abs(er) < abs(M_EPSILON*x1))
                break;
            counter++;
            if (counter > MAX_ITER)
                break;
        }
        if (counter >= MAX_ITER)
            // throw "Inaccurate sqrt exception by too many iterations.";
            throw inaccurateApproxEx;
        return x2;
    }
}

/**
  * Compute the cubic root of x to a given scale, x > 0.
  */
double newtonCbrt(double a)
{
    if (a == 0.0 || a == 1.0 || a == -1.0) {
        return a;
    }
    else if (a < 0.0) {
        return -newtonCbrt(-a);
    }
    else {
        double x1 = a;
        double x2 = (2.0*x1 + a/(x1*x1))/3.0;
        double er = x1 - x2;
        int counter = 0;
        while (x1 + er != x1) {
            x1 = x2;
            x2 = (2.0*x1 + a/(x1*x1))/3.0;
            er = x1 - x2;
            if (abs(er) < abs(M_EPSILON*x1))
                break;
            counter++;
            if (counter > MAX_ITER)
                break;
        }
        if (counter >= MAX_ITER)
            // throw "Inaccurate cbrt exception by too many iterations.";
            throw inaccurateApproxEx;
        return x2;
    }
}

/**
  * Compute the n-th root of x to a given scale, x > 0.
  */
double newtonNthRoot(int n, double a)
{
    if (n == 0) {
        return 1.0;
    }
    else if (n == 1) {
        return a;
    }
    else if (n > 0) {
        if (a == 0.0 || a == 1.0) {
            return a;
        }
        else if (a == -1.0) {
            if (n % 2 == 1)
                return a;
            else
                // throw "Cannot find the even n-th root of a negative number.";
                throw notDefinedEx;
        }
        else if (a < 0.0) {
            if (n % 2 == 1)
                return -newtonNthRoot(n, -a);
            else
                // throw "Cannot find the even n-th root of a negative number.";
                throw notDefinedEx;
        }
        else if (a < 1.0) {
            return 1.0/newtonNthRoot(n, 1.0/a);
        }
        else {
            double x1 = a;
            double xn = mPow(x1, n - 1);
            double x2 = ((n - 1)*x1 + a/xn)/n;
            double er = x1 - x2;
            int counter = 0;
            while (x1 + er != x1) {
                x1 = x2;
                xn = mPow(x1, n - 1);
                x2 = ((n - 1)*x1 + a/xn)/n;
                er = x1 - x2;
                if (abs(er) < abs(M_EPSILON*x1))
                    break;
                counter++;
                if (counter > MAX_ITER)
                    break;
            }
            if (counter >= MAX_ITER)
                // throw "Inaccurate n-th root exception by too many iterations.";
                throw inaccurateApproxEx;
            return x2;
        }
    }
    else {
        if (a == 0.0) {
            // throw "Cannot find the negative n-th root of zero.";
            throw cannotCalcEx;
        }
        else {
            return 1.0/newtonNthRoot(-n, a);
        }
    }
}

 

int main()
{
    std:cout.precision(16);

    double x = 16.0;
    double u = sqrt(x);


    cout << "[ Testing heronSqrt(double) ]--------------------" << endl;
    cout << "x = " << x << endl;
    cout << "u = sqrt(" << x << ") = " << u << endl;
    double y = heronSqrt(x);
    cout << "y = heronSqrt(" << x << ") = " << y << endl;
    cout << "y*y = " << y*y << endl;
    cout << endl;

    cout << "[ Testing newtonCbrt(double) ]--------------------" << endl;
    x = -216.0;
    cout << "x = " << x << endl;
    cout << "-exp(log(-x)/3.0) = " << -exp(log(-x)/3.0) << endl;
    double w = newtonCbrt(x);
    cout << "w = newtonCbrt(" << x << ") = " << w << endl;
    cout << "w*w*w = " << w*w*w << endl;
    cout << endl;

    x = 729000000000.0;
    cout << "x = " << x << endl;
    cout << "exp(log(x)/3.0) = " << exp(log(x)/3.0) << endl;
    w = newtonCbrt(x);
    cout << "w = newtonCbrt(" << x << ") = " << w << endl;
    cout << "w*w*w = " << w*w*w << endl;
    cout << endl;

    cout << "[ Testing newtonNthRoot(int, double) ]--------------------" << endl;
    double z = newtonNthRoot(3, x);
    cout << "x = " << x << endl;
    cout << "z = newtonNthRoot(3, " << x << ") = " << z << endl;
    cout << "z*z*z = " << z*z*z << endl;
    cout << endl;

    x = 12960000000000000000.0;
    z = newtonNthRoot(4, x);
    cout << "x = " << x << endl;
    cout << "z = newtonNthRoot(4, x) = newtonNthRoot(4, " << x << ") = " << z << endl;
    cout << "z*z*z*z = " << z*z*z*z << endl;
    cout << endl;

    x = 1.0/12960000000000000000.0;
    z = newtonNthRoot(4, x);
    cout << "x = " << x << endl;
    cout << "exp(log(x)/4.0) = " << exp(log(x)/4.0) << endl;
    cout << "z = newtonNthRoot(4, x) = newtonNthRoot(4, " << x << ") = " << z << endl;
    cout << "z*z*z*z = " << z*z*z*z << endl;
    cout << endl;


    try {
        x = -4.0;
        cout << "[ Test Exception heronSqrt(double) ]--------------------" << endl;
        cout << "x = " << x << endl;
        cout << "Calculating heronSqrt(" << x << ")" << endl;
        y = heronSqrt(x);
        cout << "y = heronSqrt(" << x << ") = " << y << endl;
        cout << "y*y = " << y*y << endl;
        cout << endl;
    }
    // catch( char *str )    {
    catch( exception& ex )    {
        cout << ex.what() << endl << "Caught some exception in calculating heronSqrt(" << x << ")" << endl;
        cout << endl;
    }

    try {
        x = -4.0;
        cout << "[ Test Exception in newtonCbrt(double) ]--------------------" << endl;
        cout << "x = " << x << endl;
        cout << "Calculating newtonCbrt(" << x << ")" << endl;
        y = newtonCbrt(x);
        cout << "y = newtonCbrt(" << x << ") = " << y << endl;
        cout << "y*y*y = " << y*y*y << endl;
        cout << endl;
    }
    // catch( char *str )    {
    catch( exception& ex )    {
        cout << ex.what() << endl << "Caught some exception in calculating newtonCbrtrt(" << x <<  ")" << endl;
        cout << endl;
    }

    cout << "[ Test calculations by powering ]-----------------------------" << endl;
    x = 200.0;
    z = newtonNthRoot(10, x);
    cout << "x = " << x << endl;
    cout << "exp(log(x)/10.0) = " << exp(log(x)/10.0) << endl;
    cout << "z = newtonNthRoot(10, x) = newtonNthRoot(10, " << x << ") = " << z << endl;
    cout << "pow(z, 10) = " << pow(z, 10) << endl;
    cout << endl;

    x = 3001.0;
    z = newtonNthRoot(99, x);
    cout << "x = " << x << endl;
    cout << "exp(log(x)/99.0) = " << exp(log(x)/99.0) << endl;
    cout << "z = newtonNthRoot(99, x) = newtonNthRoot(99, " << x << ") = " << z << endl;
    cout << "pow(z, 99) = " << pow(z, 99) << endl;
    cout << endl;

    x = 3001.0;
    z = newtonNthRoot(-99, x);
    cout << "x = " << x << endl;
    cout << "exp(log(x)/-99.0) = " << exp(log(x)/-99.0) << endl;
    cout << "z = newtonNthRoot(-99, x) = newtonNthRoot(-99, " << x << ") = " << z << endl;
    cout << "1.0/pow(z, 99) = " << 1.0/pow(z, 99) << endl;
    cout << endl;

    cout << "2.1**2.1 = pow(2.1, 2.1) = "  << pow(2.1, 2.1) << endl;
    cout << "2.1**(-2.1) = pow(2.1, -2.1) = "  << pow(2.1, -2.1) << endl;
    cout << "2.1**2.1 * 2.1**(-2.1) = pow(2.1, 2.1) * pow(2.1, -2.1) = "  << pow(2.1, 2.1)*pow(2.1, -2.1) << endl;
    cout << "2.1**2.1 = exp(2.1*log(2.1)) = "  << exp(2.1*log(2.1)) << endl;
    cout << "2.1**(-2.1) = exp(-2.1*log(2.1)) = "  << exp(-2.1*log(2.1)) << endl;
    cout << "2.1**2.1 * 2.1**(-2.1) = exp(2.1*log(2.1)) * exp(-2.1*log(2.1)) = "  << exp(2.1*log(2.1)) * exp(-2.1*log(2.1)) << endl;
    cout << endl;


    int k = 301;
    x = -1.029;
    double t1 = nPow(x, k);
    double t2 = gPow(x, k);
    double t3 = mPow(x, k);
    cout << "t1 = nPow(" << x << ", " << k << ") = " << t1 << endl;
    cout << "t2 = gPow(" << x << ", " << k << ") = " << t2 << endl;
    cout << "t3 = mPow(" << x << ", " << k << ") = " << t3 << endl;
    cout << "t1 / t2 = " << (t1 / t2) << endl;
    cout << "t1 - t2 = " << (t1 - t2) << endl;
    cout << "t1 == t2 ? " << ((t1 == t2) ? "yes" : "no") << endl;
    cout << "t1 / t3 = " << (t1 / t3) << endl;
    cout << "t1 - t3 = " << (t1 - t3) << endl;
    cout << "t1 == t3 ? " << ((t1 == t3) ? "yes" : "no") << endl;
    cout << "t2 / t3 = " << (t2 / t3) << endl;
    cout << "t2 - t3 = " << (t2 - t3) << endl;
    cout << "t2 == t3 ? " << ((t2 == t3) ? "yes" : "no") << endl;
    cout << endl;

    cout << "Done." << endl;
}

/*
Output:
[ Testing heronSqrt(double) ]--------------------
x = 16
u = sqrt(16) = 4
y = heronSqrt(16) = 4
y*y = 16

[ Testing newtonCbrt(double) ]--------------------
x = -216
-exp(log(-x)/3.0) = -6.000000000000001
w = newtonCbrt(-216) = -6
w*w*w = -216

x = 729000000000
exp(log(x)/3.0) = 9000.000000000004
w = newtonCbrt(729000000000) = 9000
w*w*w = 729000000000

[ Testing newtonNthRoot(int, double) ]--------------------
x = 729000000000
z = newtonNthRoot(3, 729000000000) = 9000
z*z*z = 729000000000

x = 1.296e+019
z = newtonNthRoot(4, x) = newtonNthRoot(4, 1.296e+019) = 60000
z*z*z*z = 1.296e+019

x = 7.716049382716049e-020
exp(log(x)/4.0) = 1.666666666666666e-005
z = newtonNthRoot(4, x) = newtonNthRoot(4, 7.716049382716049e-020) = 1.666666666
666667e-005
z*z*z*z = 7.716049382716052e-020

[ Test Exception heronSqrt(double) ]--------------------
x = -4
Calculating heronSqrt(-4)
Not defined calculation exception
Caught some exception in calculating heronSqrt(-4)

[ Test Exception in newtonCbrt(double) ]--------------------
x = -4
Calculating newtonCbrt(-4)
y = newtonCbrt(-4) = -1.587401051968199
y*y*y = -3.999999999999999

[ Test calculations by powering ]-----------------------------
x = 200
exp(log(x)/10.0) = 1.698646464634247
z = newtonNthRoot(10, x) = newtonNthRoot(10, 200) = 1.698646464634247
pow(z, 10) = 199.9999999999999

x = 3001
exp(log(x)/99.0) = 1.084236189325881
z = newtonNthRoot(99, x) = newtonNthRoot(99, 3001) = 1.084236189325881
pow(z, 99) = 3000.999999999987

x = 3001
exp(log(x)/-99.0) = 0.9223082662659932
z = newtonNthRoot(-99, x) = newtonNthRoot(-99, 3001) = 0.9223082662659932
1.0/pow(z, 99) = 3001.000000000008

2.1**2.1 = pow(2.1, 2.1) = 4.749638091742242
2.1**(-2.1) = pow(2.1, -2.1) = 0.2105423572668848
2.1**2.1 * 2.1**(-2.1) = pow(2.1, 2.1) * pow(2.1, -2.1) = 0.9999999999999999
2.1**2.1 = exp(2.1*log(2.1)) = 4.749638091742242
2.1**(-2.1) = exp(-2.1*log(2.1)) = 0.2105423572668848
2.1**2.1 * 2.1**(-2.1) = exp(2.1*log(2.1)) * exp(-2.1*log(2.1)) = 1

t1 = nPow(-1.029, 301) = -5457.92801577163
t2 = gPow(-1.029, 301) = -5457.928015771692
t3 = mPow(-1.029, 301) = -5457.928015771692
t1 / t2 = 0.9999999999999887
t1 - t2 = 6.184563972055912e-011
t1 == t2 ? no
t1 / t3 = 0.9999999999999887
t1 - t3 = 6.184563972055912e-011
t1 == t3 ? no
t2 / t3 = 1
t2 - t3 = 0
t2 == t3 ? yes

Done.
*/

 

 

Posted by Scripter
,

역삼각함수란 삼각함수의 역함수를 의미하고,

역쌍곡선함수란 쌍곡선함수의 역함수를 의미한다.

수학에서 sin 함수의 역함수는 arcsin 으로 표기되는데,

 C 언어나 C++ 언어에서는 asin 함수로 구현되어 있다.

아래의 소스는 Visual C++ 또는 g++ 로 컴파일되는 소스이다. 실행 결과는 같다.

 

/*
 * Filename: testArcSine.cpp
 *
 * Compile: cl /EHsc testArcSine.cpp
 * Execute: testArcSine
 *
 * Or
 *
 * Cpmpile: g++ -o testArcSine testArcSine.cpp
 * Execute: ./testArcSine
 *
 * Date: 2013. 1. 1.
 * Copyright (c) pkim _AT_ scripts.pe.kr
 */
 
#include <iostream>
#include <cmath>

double asinh(double x) {
    double y = log(x + sqrt(x*x + 1));
    return y;
}

double acosh(double x) {
    double y = log(x + sqrt(x*x - 1));
    return y;
}

int main() {
 
 std::cout.precision(10);
 
 double x = -0.9;
 double y = asin(x);
 std::cout << "y = asin(" << x << ") = " << y << std::endl;
 std::cout << "sin(y) = sin(" << y << ") = " << sin(y) << std::endl;
  std::cout << std::endl;
 
 x = 1.1;
 double u = acosh(x);
 std::cout << "u = acosh(" << x << ") = " << u << std::endl;
 
 double v = asinh(x);
 std::cout << "v = asinh(" << x << ") = " << v << std::endl;
 
 std::cout << "cosh(u) = cosh(" << u << ") = " << cosh(u) << std::endl;
 std::cout << "sinh(v) = sinh(" << v << ") = " << sinh(v) << std::endl;
 
    return 0;
}

/*
Output:
y = asin(-0.9) = -1.119769515
sin(y) = sin(-1.119769515) = -0.9

u = acosh(1.1) = 0.4435682544
v = asinh(1.1) = 0.9503469298
cosh(u) = cosh(0.4435682544) = 1.1
sinh(v) = sinh(0.9503469298) = 1.1
*/

 

 

Posted by Scripter
,

이전에는 MinGW 의 gcc 버전이 낮아서 gmp, mpfr 을 사용하는데 핸디캡이 있었지만, 지금은 MinGW 의 gcc  버전이 4.6.x 대로 높아져서 꽤 쓸만한 개발도구가 되었다.

그래서 MinGW 의 설치 방법과 gmp, mpfr 라이브러리를 사용하는 방법을 남겨 둔다.

MinGW 는 Minimalist GNU for Windows 를 줄인 굴이라고 보면 이애하기가 쉬울 것이다.

 

* 윈도우 환경에  MinGW 및 MSYS 설치하기


무료로 쓰는 GNU C/C++ 컴파일러를 사용하기 위해서, 윈도우에 cygwin을 설치하는 일은 다소 무겁다는 생각이 든다. 이럴 때는 MinGW와 MSYS를 설치하면 간단한 C/C++ 개발 환경이 구축된다.

MinGW는 윈도우용 GCC Compiler Toolchain이고,
MSYS(Minal SYStem)로 윈도우에서 리눅스 쉘(Linux Shell)과 Binutils 환경을 제공한다.


  1.  최신 MinGW GUI 인스틀러 다운로드

         - MinGW와 MYS의 설치는 GUI 인스톨러를 사용하면 설치 과정이 간단하다.

 

     < GUI 인스톨러를 실행한 첫 화면 >

 

     < 설치 과정 중에 모든 설치 옵션을 체크한다. >

 

     < 설치 과정 중에 MSYS 옵션도 체크해야 한다. >

 

 

 2. MinGW 의 설치 확인

명령프롬프트> set PATH=c:\MinGW\bin;%PATH%

명령프롬프트> gcc -v

Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=c:/mingw/bin/../libexec/gcc/mingw32/4.6.2/lto-wrapper.exe
Target: mingw32
Configured with: ../gcc-4.6.2/configure --enable-languages=c,c++,ada,fortran,obj
c,obj-c++ --disable-sjlj-exceptions --with-dwarf2 --enable-shared --enable-libgo
mp --disable-win32-registry --enable-libstdcxx-debug --enable-version-specific-r
untime-libs --build=mingw32 --prefix=/mingw
Thread model: win32
gcc version 4.6.2 (GCC)


 

 3. MSYS 환경 없이 MinGW 의 gcc, g++ 사용하기

         명령프롬프트> set PATH=c:\MinGW\bin;%PATH%

         명령프롬프트> g++ -o rpnSTL rpnSTL.cpp

         명령프롬프트> rpnSTL

 

 4. MSYS 환경  하레 MinGW 의 gcc, g++ 사용하기

         명령프롬프트> set PATH=c:\MinGW\bin;c:\MinGW\msys\1.0\bin;%PATH%

         명령프롬프트> msysmnt

         명령프롬프트> bash

         $  g++ -o rpnSTL rpnSTL.cpp
 
         $  ./rpnSTL



[ STL을 이용하는 C++ 예제 소스:  rpnSTL.cpp ]

   (참고: GCC 4.6.2 용으로 수정됨, atof() 대신 ::strtod() 사용하는 것으로 수정함.)

// stl/rpnSTL.cpp -- RPN (Reverse Polish Notation) Calculator
//
//  Modified by PH Kim, 2012-12-31
//
//  Which are different from the original source rpn.cpp ?
//
//      1. double instead of int
//      2. negative value possible
//      3. support the power operator ^
//      4. support for gcc 4.6.2
//      5. etc
//
//  Compile:
//      [Borland C++ 5.5.1]  bcc32 rpnSTL.cpp
//        [Visual C++ 2008]  cl /EHsc rpnSTL.cpp
//                [GNU C++]  g++ -o rpnSTL rpnSTL.cpp
//
//  Execute:  rpnSTL
//            ./rpnSTL
//
// Original from:
//    http://www.fredosaurus.com/notes-cpp/examples/rpn/rpn.html
// ---------------------------------------------------------
// stl/rpn.cpp -- RPN (Reverse Polish Notation) Calculator
// Fred Swartz 2001-12-05, 2002-09-27
// ---------------------------------------------------------

#include <iostream>
#include <vector>
#include <string>
#include <cmath>
#include <stdexcept>
#include <cstdlib>    // required for ::strtod()
using namespace std;
//--- prototypes
double pop(vector<double>& stk);
void printVector(vector<double>& stk);
void clearVector(vector<double>& stk);
void printUsage();

//============================================================= main
int main() {
    vector<double> opndStack; // vector used as operand stack
    string token;          // to read number or operator
    cout << "RPN Calculator" << endl;
    printUsage();
    while (cin >> token) {
        if (isdigit(token[0]) || (token.length() > 1 && (token[0] == '-' || token[0] == '+') && isdigit(token[1]))) { // if first is digit, it's number.
             // opndStack.push_back(atof(token.c_str())); // convert, push
             // Note that atof(str) has been changed to ::strtod(str, 0)
             opndStack.push_back(::strtod(token.c_str(), 0)); // convert, push
            printVector(opndStack);

        } else { // If it's not a number, assume it's an operator
            double left, right;  //  used by some operators as temps
            switch (token[0]) {  // assume operators are one char
              case '+': opndStack.push_back(pop(opndStack) + pop(opndStack));
                        break;
              case '-': right = pop(opndStack); // get right operand
                        left  = pop(opndStack); // get left operand
                        opndStack.push_back(left - right);
                        break;
              case '*': opndStack.push_back(pop(opndStack) * pop(opndStack));
                        break;
              case '/': right = pop(opndStack); // get right operand
                        left  = pop(opndStack); // get left operand
                        opndStack.push_back(left / right);
                        break;
              case '^': right = pop(opndStack); // get right operand
                        left  = pop(opndStack); // get left operand
                        opndStack.push_back(pow(left, right));
                        break;
              case '=':
              case 'p':
                        break;
              case 'c':
                        clearVector(opndStack);
                        break;
              case 'q':
              case 'x':
                        cout << "Quit" << endl;
                        exit(0);
                        break;
              case 'h':
                        printUsage();
                        break;
              default:  throw domain_error("Undefined operator");
            }
            printVector(opndStack);
            if (!opndStack.empty())
                cout << "    (" << token[0] << ") Top value: " << opndStack.back() << endl;
        }
    }
    return 0;
}//end main

//============================================================== pop
   // This utility function checks stack for underflow
   // and pops (removes and returns) last element.
double pop(vector<double>& stk) {
    if (stk.empty()) {
        throw underflow_error("Stack underflow.");
    }
    double result = stk.back();
    stk.pop_back();
    return result;
}//end pop

double peek(vector<double>& stk) {
    if (stk.empty()) {
        throw underflow_error("Stack underflow.");
    }
    return stk.back();
}//end pop

void printVector(vector<double>& stk) {
    int n = stk.size();
    cout << "[";
    for (int i = 0; i < n; i++) {
       cout << stk[i];
       if (i < n - 1)
           cout <<", ";
    }
    cout << "]" << endl;
}//end printVector

void clearVector(vector<double>& stk) {
    while (!stk.empty()) {
       stk.erase(stk.begin());
       // stk.pop_back();
    }
}//end clearVector
void printUsage() {
    cout << "  +,-,*,/,^: opr,  =,p: show top,  c: clear stack,  q,x: quit,  h: help" << endl;
}//end printVector

/*
// stl/rpn.cpp -- RPN (Reverse Polish Notation) Calculator
// Fred Swartz 2001-12-05, 2002-09-27
#include <iostream>
#include <vector>
#include <string>
#include <stdexcept>
using namespace std;
int pop(vector<int>& stk);  //--- prototype to pop stack
//============================================================= main
int main() {
    vector<int> opndStack; // vector used as operand stack
    string token;          // to read number or operator
    while (cin >> token) {
        if (isdigit(token[0])) { // if first is digit, it's number.
            opndStack.push_back(atoi(token.c_str())); // convert, push

        } else { // If it's not a number, assume it's an operator
            int left, right;  //  used by some operators as temps
            switch (token[0]) {  // assume operators are one char
              case '+': opndStack.push_back(pop(opndStack) + pop(opndStack));
                        break;
              case '-': right = pop(opndStack); // get right operand
                        left  = pop(opndStack); // get left operand
                        opndStack.push_back(left - right);
                        break;
              case '*': opndStack.push_back(pop(opndStack) * pop(opndStack));
                        break;
              case '/': right = pop(opndStack); // get right operand
                        left  = pop(opndStack); // get left operand
                        opndStack.push_back(left / right);
                        break;
              default:  throw domain_error("Undefined operator");
            }
            cout << "Result: " << opndStack.back() << endl;
        }
    }
    return 0;
}//end main
//============================================================== pop
   // This utility function checks stack for underflow
   // and pops (removes and returns) last element.
int pop(vector<int>& stk) {
    if (stk.empty()) {
        throw underflow_error("Stack underflow.");
    }
    int result = stk.back();
    stk.pop_back();
    return result;
}//end pop
*/



Posted by Scripter
,

아래의 소스는 윈도우에서

            Luna MinGW & GNU C 4.5.0 (gcc), 

로 테스트되었다. long 타입으로는 13! 까지만 정확하계 계산되지만 GMP 를 이용한 계산은 아무리 큰 수의 곱셈이라도 정확히 계산해준다.

  • 윈도우에 Luna MinGW (with GCC 4.5.0) 설치하기:
     1) Luna MinGW 홈페이지(MinGW GCC C/C++ Compiler package with installer) 
     2) Luna MinGW 설치파일 다운로드
  •  영문  위키피디아에서 소개하는 MinGW
  • MinGW 의 공식 웹사이트에서 MinGW 를 설치하면 gcc 버전이 3.4.5 밖에 되지 않고,
    gmp 라이브러리도 수동으로 설치헤야 하는 번거로움이 있으므로,
    여기서는 Luna MinGW 를 설치하기로 한다. Luna MinGW 를 설치하면,
    현재 최신 버전인 gcc4.5.0 을 쓸 수 있다. 그 대신 g++ 로 컴파일 후에 쓰일 런타임 다이나믹  라이브러리 libgmpxx-4.dll 은 별도로 구하여 설치해야 한다.
  • 윈도우에 Luna MinGW (with GCC 4.5.0) 설치하기:
        * Luna MinGW 홈페이지(MinGW GCC C/C++ Compiler package with installer) 
        * Luna MinGW 설치파일 다운로드
    1) 설치는 C:\MinGW 에 한것으로 간주한다.
    2) gcc 에서 gmp 라이브러리는 추가 설치 없이 바로 쓸 수 있는데,
        g++ 로는 컴파일은 되지만 컴파일된 실행파일을 실행하면 
        limgmpxx-4.dll 파일이 없다고 에러가 날 것이다. 이때는 아래 처럼 
        limgmpxx-4.dll 파일을 컴파일해서 만들던가 이미 만들어진 것을 PATH 가 걸려 있는 곳에 넣어두어야 한다. 아래는 limgmpxx-4.dll 파일을 구할 수 있는 곳이다. 
  • g++에서 gmp를 사용하기 위해 libgmpxx-4.dll 구하여 설치하기:
       * 소스포지에서 libgmpxx-5.0.1-1-mingw32-dll-4.tar.lzma 다운로드하기
    1)  확장명이 lzma 인 파일은 7zip 으로 풀어야 한다. (7zip 은 http://www.7-zip.org 에서 구한다.)
    2) 위의 파일을 받아서 7zip으로 압축 해제하여 libgmpxx-4.dll 을  C:\MinGW\bin 에 복사힌다.  (C:\MinGW 은 Luna MinGW 가 설치된 디렉토리이다)
  • gcc 버전 확인하기
    프롬프트> gcc -v
    Using built-in specs.
    COLLECT_GCC=gcc
    COLLECT_LTO_WRAPPER=c:/mingw/bin/../libexec/gcc/mingw32/4.5.0/lto-wrapper.exe
    Target: mingw32
    Configured with: ../gcc-4.5.0/configure --enable-languages=c,c++,ada,fortran,obj
    c,obj-c++ --disable-sjlj-exceptions --with-dwarf2 --enable-shared --enable-libgo
    mp --disable-win32-registry --enable-libstdcxx-debug --enable-version-specific-r
    untime-libs --disable-werror --build=mingw32 --prefix=/mingw
    Thread model: win32
    gcc version 4.5.0 (GCC)
  • g++ 버전 확인하기
    프롬프트> g++ -v
    Using built-in specs.
    COLLECT_GCC=g++
    COLLECT_LTO_WRAPPER=c:/mingw/bin/../libexec/gcc/mingw32/4.5.0/lto-wrapper.exe
    Target: mingw32
    Configured with: ../gcc-4.5.0/configure --enable-languages=c,c++,ada,fortran,obj
    c,obj-c++ --disable-sjlj-exceptions --with-dwarf2 --enable-shared --enable-libgo
    mp --disable-win32-registry --enable-libstdcxx-debug --enable-version-specific-r
    untime-libs --disable-werror --build=mingw32 --prefix=/mingw
    Thread model: win32
    gcc version 4.5.0 (GCC)



    * 소스 파일명: recFactGMPcpp01.cc

/*
 *  Filename: recFactGMPcpp01.cc
 *
 *  Compile: g++ -o recFactGMPcpp01 recFactGMPcpp01.cc -lgmpxx -lgmp
 */

#include <iostream>
#include <gmpxx.h>

using namespace std;

mpz_class factorial(int n) {
    static mpz_class v;
    v = 1;
    for (int i = 1; i <= n; i++) {
     v = v*i;
    }
    return v;
}

int main(int argc, char *argv[]) {
    int n1 = 9;
    int n2 = 30;
    for (int i = n1; i <= n2; i++) {
        cout << i << "! = " << factorial(i) << endl;
        if (i == 13)
            cout << "-- below calc are regular ----" << endl;
    }
    return 0;
}




실행 결과:
프롬프트> recFactGMPcpp01
9! = 362880
10! = 3628800
11! = 39916800
12! = 479001600
13! = 6227020800
-- below calc are regular ----
14! = 87178291200
15! = 1307674368000
16! = 20922789888000
17! = 355687428096000
18! = 6402373705728000
19! = 121645100408832000
20! = 2432902008176640000
21! = 51090942171709440000
22! = 1124000727777607680000
23! = 25852016738884976640000
24! = 620448401733239439360000
25! = 15511210043330985984000000
26! = 403291461126605635584000000
27! = 10888869450418352160768000000
28! = 304888344611713860501504000000
29! = 8841761993739701954543616000000
30! = 265252859812191058636308480000000



Posted by Scripter
,


[파일명:  TestStringFindInList.cpp]------------------------------------------------
// Filename: TestStringFindInList.cpp
//
// Compile: cl /clr TestStringFindInList.cpp
// Execute: TestStringFindInList

#using <mscorlib.dll>
#using <System.dll>

using namespace System;
using namespace System::Collections;
using namespace System::Collections::Generic;

void PrintArray(List<String^>^ arr);

bool Contains(String^ s)
{
    return s->IndexOf("셋") >= 0;
}

int main(array<String^> ^args) {
    List<String^>^ words = gcnew List<String^>( gcnew array<String^> { "하나", "둘", "셋", "넷", "다섯", "여섯" } );
    int where;

    Console::Write("list: ");
    PrintArray(words);
    where = words->FindIndex(gcnew Predicate<String^>(Contains));
    if (where >= 0) {
        Console::Write("발견!  ");
        Console::WriteLine("Next word of 셋 in list: {0}", words[where+1]);
    }

    Console::WriteLine("Sorting...");
    words->Sort();

    Console::Write("list: ");
    PrintArray(words);
    where = words->FindIndex(gcnew Predicate<String^>(Contains));
    if (where >= 0) {
        Console::Write("발견!  ");
        Console::WriteLine("Next word of 셋 in list: {0}", words[where+1]);
    }

    return 0;
}
  
void PrintArray(List<String^>^ arr) {
    Console::Write("[");
    for (int i = 0; i < arr->Count - 1; i++) {
        Console::Write("{0}, ", arr[i]);
    }
    if (arr->Count > 0)
        Console::Write("{0}", arr[arr->Count - 1]);
    Console::WriteLine("]");
}
------------------------------------------------


컴파일> cl /clr testStringFindInList.cpp

실행> TestStringFindInList
list: [하나, 둘, 셋, 넷, 다섯, 여섯]
발견!  Next word of 셋 in list: 넷
Sorting...
list: [넷, 다섯, 둘, 셋, 여섯, 하나]
발견!  Next word of 셋 in list: 여섯


크리에이티브 커먼즈 라이선스
Creative Commons License

 

Posted by Scripter
,


[파일명:  TestStringFindApp.cpp]------------------------------------------------
// Filename: TestStringFindApp.cpp
//
// Compile: cl /clr TestStringFindApp.cpp
// Execute: TestStringFindApp

using namespace System;
using namespace System::Collections;
using namespace System::Collections::Generic;

void PrintArray(array<String^>^ arr);

bool Contains(String^ s)
{
    return s->IndexOf("셋") >= 0;
}

int main(array<String^> ^args) {
    array<String^>^ words = gcnew array<String^> { "하나", "둘", "셋", "넷", "다섯", "여섯" };
    int where;

    Console::Write("array: ");
    PrintArray(words);
    where = Array::FindIndex(words, gcnew Predicate<String^>(Contains));
    if (where >= 0) {
        Console::Write("발견!  ");
        Console::WriteLine("Next word of 셋 in array: {0}", words[where+1]);
    }

    Console::WriteLine("Sorting...");
    Array::Sort(words);

    Console::Write("array: ");
    PrintArray(words);
    where = Array::FindIndex(words, gcnew Predicate<String^>(Contains));
    if (where >= 0) {
        Console::Write("발견!  ");
        Console::WriteLine("Next word of 셋 in array: {0}", words[where+1]);
    }

    return 0;
}
  
void PrintArray(array<String^>^ arr) {
    Console::Write("[");
    for (int i = 0; i < arr->Length - 1; i++) {
        Console::Write("{0}, ", arr[i]);
    }
    if (arr->Length > 0)
        Console::Write("{0}", arr[arr->Length - 1]);
    Console::WriteLine("]");
}
------------------------------------------------


컴파일> cl /clr testStringFindApp.cpp

실행> TestStringFindApp
array: [하나, 둘, 셋, 넷, 다섯, 여섯]
발견!  Next word of 셋 in array: 넷
Sorting...
array: [넷, 다섯, 둘, 셋, 여섯, 하나]
발견!  Next word of 셋 in array: 여섯


크리에이티브 커먼즈 라이선스
Creative Commons License

 

Posted by Scripter
,