다음은 초등학교에서 배우는 나눗셈 계산표를 만들어주는 C++ 소스 코드이다.
나눗셈 계산표를 완성하고 나서 약수, 배수 관계를 알려준다.


  1. /*
  2.  *  Filename: makeDivisionTableCPP.cpp
  3.  *
  4.  *  Purpose:  Make a division table in a handy written form.
  5.  *
  6.  *  Compile: cl /GX makeDivisionTableCPP.cpp
  7.  *
  8.  *  Execute: makeDivisionTableCPP 12345 32
  9.  *           makeDivisionTableCPP 500210 61
  10.  *
  11.  *     Date:  2008/05/15
  12.  *   Author:  PH Kim   [ pkim ((AT)) scripts.pe.kr ]
  13.  */
  14. #include <iostream>
  15. #include <string>
  16. #include <cmath>
  17. #include <memory>
  18. using namespace std;
  19. enum { FALSE, TRUE };
  20. void println(char s[]) {
  21.     cout << s << endl;
  22. }
  23. void print(char s[]) {
  24.     cout << s;
  25. }
  26. void printUsage() {
  27.     // println("Using: makeDivisionTable [numerator] [denominator]");
  28.     // println("Make a division table in a handy written form.");
  29.     println("사용법: makeDivisionTable [피제수] [제수]");
  30.     println("손으로 작성한 형태의 나눗셈 표를 만들어준다.");
  31. }
  32. // 부동소수점수의 표현이 .0 으로 끝나는 경우 이를 잘라낸다.
    // 전체 문자열 표시 너비는 매개변수 width 로 전달받아 처리한다.
  33. char *simplify(double v, int width) {
  34.     int n, len;
  35.     static char t[] = "                               ";
  36.     char tmp[] = "                               ";
  37.     sprintf(t, "%g", v);
  38.     n = strlen(t);
  39.     if ((n > 2) && (t[n - 2] == '.') && (t[n - 1] == '0'))
  40.         t[n-2] = '\0';
  41.     len = strlen(t);
  42.     strcpy(tmp, t);
  43.     if (len < width) {
  44.         strncpy(t, "               ", width - len);
  45.         t[width - len] = '\0';
  46.         strcat(t, tmp);
  47.     }
  48.     return (char *) t;
  49. }
  50. // 발음상 숫자에 맞는 주어 조사 "은", "는"을 결정한다.
  51. void getSuffix(char *buf, long v) {
  52.     long t = v % 10L;
  53.     char suffix[3];
  54.     char tbuf[2];
  55.     char suf[2][3] = { "은",  "는"};
  56.     strcpy(suffix, suf[0]);
  57.     sprintf(tbuf, "%d", t);
  58.     if (strchr("2459", tbuf[0]) != NULL) {
  59.         strcpy(suffix, suf[1]);
  60.     }
  61.     strcpy(buf, suffix);
  62. }
  63. long makeTable(long numer, long denom, long quotient) {
  64.     char sbuf[81];
  65.     char strNumer[40];
  66.     char strDenom[40];
  67.     char strQuotient[40];
  68.     char strTmpR[40];
  69.     char whiteChars[] = "                                                                                 ";
  70.     char underbarChars[]  = "_________________________________________________________________________________";
  71.     char barChars[]  = "---------------------------------------------------------------------------------";
  72.     char offsetSpaces[81];
  73.     char biasSpaces[81];
  74.     char spaces[81];
  75.     char uline[81];
  76.     char sline[81];
  77.     int i;
  78.     int lenN;
  79.     int lenD;
  80.     int lenQ;
  81.     int offsetLeft;
  82.     int bias;
  83.     long tmpR;
  84.     long tmpSub;
  85.     char oneDigit;
  86.     sprintf(strNumer, "%ld", numer);
  87.     sprintf(strDenom, "%ld", denom);
  88.     sprintf(strQuotient, "%ld", quotient);
  89.     lenN = strlen(strNumer);
  90.     lenD = strlen(strDenom);
  91.     lenQ = strlen(strQuotient);
  92.     offsetLeft = 3 + lenD + 3;
  93.     bias = lenN - lenQ;
  94.     strncpy(offsetSpaces, whiteChars, offsetLeft);
  95.     offsetSpaces[offsetLeft] = '\0';
  96.     strncpy(biasSpaces, whiteChars, bias);
  97.     biasSpaces[bias] = '\0';
  98.     strncpy(uline, underbarChars, lenN + 2);
  99.     uline[lenN + 2] = '\0';
  100.     strncpy(sline, barChars, lenN);
  101.     sline[lenN] = '\0';
  102.     printf("%s%s%ld\n", offsetSpaces, biasSpaces, quotient);
  103.     sprintf(sbuf, offsetSpaces);
  104.     sbuf[offsetLeft - 2] = '\0';
  105.     printf("%s%s\n", sbuf, uline);
  106.     printf("   %s ) %s", strDenom, strNumer);
  107.     strncpy(strTmpR, strNumer, bias + 1);
  108.     strTmpR[bias + 1] = '\0';
  109.     tmpR = atoi(strTmpR);
  110.     tmpSub = 0L;
  111.     for (i = 0; i < lenQ; i++) {
  112.         if (strQuotient[i] == '0') {
  113.             if (i + 1 < lenQ) {
  114.                 oneDigit = strNumer[bias + i + 1];
  115.                 printf("%c", oneDigit);
  116.                 sprintf(sbuf, "%c", oneDigit);
  117.                 strcat(strTmpR, sbuf);
  118.                 tmpR = atoi(strTmpR);
  119.             }
  120.         }
  121.         else {
  122.             println("");
  123.             tmpSub = (long)(strQuotient[i] - '0') * denom;
  124.             printf("%s%s\n", offsetSpaces, simplify(tmpSub, bias + i + 1));
  125.             printf("%s%s\n", offsetSpaces, sline);
  126.             tmpR = tmpR - tmpSub;
  127.             if (tmpR == 0L && i + 1 < lenQ) {
  128.                 strncpy(sbuf, whiteChars, bias + i + 1);
  129.                 sbuf[bias + i + 1] = '\0';
  130.                 printf("%s%s", offsetSpaces, sbuf);
  131.             }
  132.             else {
  133.                 printf("%s%s", offsetSpaces, simplify(tmpR, bias + i + 1));
  134.             }
  135.             sprintf(strTmpR, "%ld", tmpR);
  136.             if (i + 1 < lenQ) {
  137.                 oneDigit = strNumer[bias + i + 1];
  138.                 printf("%c", oneDigit);
  139.                 sprintf(sbuf, "%c", oneDigit);
  140.                 strcat(strTmpR, sbuf);
  141.                 tmpR = atoi(strTmpR);
  142.             }
  143.         }
  144.     }
  145.     println("");
  146.     return tmpR;
  147. }
  148. // C/C++/Ch 언어의 실행 시작 지점
  149. int main(int argc, char *argv[]) {
  150.     int i;
  151.     int SIZE = argc - 2;
  152.     long a, b, q, r, k;
  153.     char mbuf[3];
  154.     if (argc < 3) {
  155.         printUsage();
  156.         exit(1);
  157.     }
  158.     a = atoi(argv[1]);
  159.     b = atoi(argv[2]);
  160.     if (a <= 0L) {
  161.         printf("피제수: %ld\n", a);
  162.         println("피제수는 양의 정수라야 합니다.");
  163.         exit(1);
  164.     }
  165.     if (b <= 0L) {
  166.          printf("제수: %ld\n", b);
  167.          println("제수는 양의 정수라야 합니다.");
  168.          exit(1);
  169.     }
  170.     q = a / b;
  171.     r = a % b;
  172.     printf("나눗셈 %ld ÷ %ld 의 결과: ", a, b);
  173.     printf("몫: %ld, ", q);
  174.     printf("나머지: %ld\n", r);
  175.     println("");
  176.     k = makeTable(a, b, q);
  177.     if (k == r) {
            printf("\n나머지: %ld\n", k);
  178.     }
  179.     if (k == 0L) {
  180.         printf("%ld = %ld x %ld\n", a, b, q);
  181.         getSuffix(mbuf, a);
  182.         printf("%ld%s %ld의 배수(mupltiple)이다.\n", a, mbuf, b);
  183.         getSuffix(mbuf, b);
  184.         printf("%ld%s %ld의 약수(divisor)이다.\n", b, mbuf, a);
  185.     }
  186.     else {
  187.         getSuffix(mbuf, a);
  188.         printf("%ld = %ld x %ld + %ld\n", a, b, q, r);
  189.         printf("%ld%s %ld의 배수(mupltiple)가 아니다.\n", a, mbuf, b);
  190.     }
  191.     return 0;
  192. }




실행> makeDivisionTableCPP 500210 61

나눗셈 500210 ÷ 61 의 결과: 몫: 8200, 나머지: 10

          8200
      ________
   61 ) 500210
        488
        ------
         122
         122
        ------
            10

나머지: 10
500210 = 61 x 8200 + 10
500210은 61의 배수(mupltiple)가 아니다.




Creative Commons License

이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.

Posted by Scripter
,

C++ 소스는 한 개의 파일에 여러 개의 클래스가 존재해도 된다.

다음은 두 개의 클래스로 구성되어 있다.
Parent는 부모 클래스이고 Child는 Parent에서 상속 받은 자식 클래스이다.



// Filename: testSubclassing.cpp
#include <iostream>

using namespace std;

class Parent {
    private:
        char name[21];
    public:
        Parent(const char *);        // 생성자
        ~Parent() {   }                 // 소멸자
        void sayName();
};

class Child : public Parent {
    private:
        char name[21];
    public:
        Child(const char *);           // 생성자
        ~Child() {   }                    // 소멸자
        void sayName();
};

Parent :: Parent(const char *sname) {
    strcpy(name, sname);
}

void Parent :: sayName() {
    cout << "I am Parent, " << name << endl;
}

Child :: Child(const char *sname) : Parent(sname) {
    strcpy(name, sname);
}

void Child :: sayName() {
    cout << "I am a child, named as " << name << endl;
}

void main(void) {
    Child obj("Dooly");
    obj.sayName();
}




Visual C++ 6 로 컴파일할 경우 컴파일 명령은

     cl -GX testSubclassing.cpp

이다.


실행> testSubclassing
I am a child, named as Dooly




Linux/Unix 플랫폼에서 g++로 컴파일 하려면 main() 함수를 다소 수정해야 한다.

int main(void) {
    Child obj("Dooly");
    obj.sayName();
    return 0;
}

그리고 저장되는 소스 파일명도 testSubClassing.cc 로 한다.



컴파일> g++ testSubclassing.cc

실행> ./a.out
I am a child, named as Dooly


또는

컴파일> g++ -o testSubclassing testSubclassing.cc

실행> ./testSubclassing
I am a child, named as Dooly




Creative Commons License

이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.

Posted by Scripter
,

ASCII(애스키)란 American Standard Code for Information Interchange의 줄임글로서, 영문자에 기초한 문자 인코딩이다.  이 문자 인코딩에는 C0 제어문자(C0 control character)도 포함되어 있다.  ( 참고:  ASCII - Wikipedia, the free encyclopedia )

다음은  7bit ASCII 코드표를 만들어 보여주는 자바 소스 코드이다. 소스 코드 중에 진법변환에 필요한 함수

        convertAtoI()
        convertItoA()

의 구현도 포함되어 있다.



  1. /*
  2.  *  Filename: makeAsciiTableCPP.cpp
  3.  *            Make a table of ascii codes.
  4.  *
  5.  *  Compile: cl /GX makeAsciiTableCPP.cpp
  6.  *  Execute: makeAsciiTable
  7.  *
  8.  *      Date:  2008/03/27
  9.  *    Author:  PH Kim   [ pkim (AT) scripts.pe.kr ]
  10.  */
  11. #include <iostream>
  12. #include <string>
  13. #include <cmath>
  14. using namespace std;
  15. #define MAX_BUF 81
  16. enum { FALSE, TRUE };
  17. void println(char s[]) {
  18.     cout << s << endl;
  19. }
  20. void print(char s[]) {
  21.     cout << s;
  22. }
  23. void printUsage() {
  24.     println("Usage: makeAsciiTable");
  25.     println("Make a table of ascii codes.");
  26. }
  27. char BASE36[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  28. void convertItoA(char *pstr, long num, int radix) {
  29.     char tmp[2];
  30.     char ret[MAX_BUF];
  31.     char arr[MAX_BUF];
  32.     long q, r;
  33.     int i, n;
  34.     int isNegative = FALSE;
  35.     if (num < 0L) {
  36.         isNegative = TRUE;
  37.         num = -num;
  38.     }
  39.     arr[0] = '\0';
  40.     q = num;
  41.     r = 0L;
  42.     while (q >= (long) radix) {
  43.         r = q % (long) radix;
  44.         q = q / (long) radix;
  45.         tmp[0] = BASE36[r];
  46.         tmp[1] = '\0';
  47.         strcat(arr, tmp);
  48.     }
  49.     tmp[0] = BASE36[q];
  50.     tmp[1] = '\0';
  51.     strcat(arr, tmp);
  52.     if (isNegative) {
  53.         strcat(arr, "-");
  54.     }
  55.     n = strlen(arr);
  56.     for (i = 0; i < n; i++) {
  57.         ret[i] = arr[n - i - 1];
  58.     }
  59.     ret[n] = '\0';
  60.     strcpy(pstr, (char *) ret);
  61. }
  62. long convertAtoI(const char *pstr, int radix) {
  63.     char tmp[2];
  64.     long ret = 0L;
  65.     char arr[MAX_BUF];
  66.     long q, r;
  67.     int isNegative = FALSE;
  68.     int len = strlen(pstr);
  69.     char c;
  70.     int i;
  71.     long val;
  72.     c = pstr[0];
  73.     if (c == '-') {
  74.        isNegative = TRUE;
  75.     }
  76.     else if (c >= '0' && c <= '9') {
  77.         ret = (long) (c - '0');
  78.     }
  79.     else if (c >= 'A' && c <= 'Z') {
  80.         ret = (long) (c - 'A') + 10L;
  81.     }
  82.     else if (c >= 'a' && c <= 'z') {
  83.         ret = (long) (c - 'a') + 10L;
  84.     }
  85.     if (ret >= (long) radix) {
  86.         println("        Invalid character!");
  87.         return ret;
  88.     }
  89.     for (i = 1; i < len; i++) {
  90.         c = pstr[i];
  91.         ret *= radix;
  92.         if (c >= '0' && c <= '9') {
  93.             val = (long) (c - '0');
  94.         }
  95.         else if (c >= 'A' && c <= 'Z') {
  96.             val = (long) (c - 'A') + 10L;
  97.         }
  98.         else if (c >= 'a' && c <= 'z') {
  99.             val = (long) (c - 'a') + 10L;
  100.         }
  101.         if (val >= (long) radix) {
  102.             println("        Invalid character!");
  103.             return ret;
  104.         }
  105.         ret += val;
  106.     }
  107.     return ret;
  108. }
  109. char asc[33][4]  = {
  110.      "NUL", "SOH", "STX", "ETX", "EOT",
  111.      "ENQ", "ACK", "BEL", "BS", "HT",
  112.      "LF", "VT", "FF", "CR", "SO",
  113.      "SI", "DLE", "DC1", "DC2", "DC3",
  114.      "DC4", "NAK", "SYN", "ETB", "CAN",
  115.      "EM", "SUB", "ESC", "FS", "GS",
  116.      "RS", "US", "Spc"
  117.  };
  118. char control[33][36]  = {
  119.         "NUL (null)",
  120.         "SOH (start of heading)",
  121.         "STX (start of text)",
  122.         "ETX (end of text)",
  123.         "EOT (end of transmission)",
  124.         "ENQ (enquiry)",
  125.         "ACK (acknowledge)",
  126.         "BEL (bell)",
  127.         "BS  (backspace)",
  128.         "TAB (horizontal tab)",
  129.         "LF  (line feed, NL new line)",
  130.         "VT  (vertical tab)",
  131.         "FF  (form feed, NP new page)",
  132.         "CR  (carriage return)",
  133.         "SO  (shift out)",
  134.         "SI  (shift in)",
  135.         "DLE (data link escape)",
  136.         "DC1 (device control 1)",
  137.         "DC2 (device control 2)",
  138.         "DC3 (device control 3)",
  139.         "DC4 (device control 4)",
  140.         "NAK (negative acknowledge)",
  141.         "SYN (synchronous idle)",
  142.         "ETB (end of trans. block)",
  143.         "CAN (cancel)",
  144.         "EM  (end of medium)",
  145.         "SUB (substitute, EOF end of file)",
  146.         "ESC (escape)",
  147.         "FS  (file separator)",
  148.         "GS  (group separator)",
  149.         "RS  (record separator)",
  150.         "US  (unit separator)",
  151.     };
  152. void makeTable() {
  153.     char sbuf[MAX_BUF];
  154.     char abuf[MAX_BUF/2];
  155.     char tbuf[MAX_BUF/2];
  156.     int i, j;
  157.     unsigned char c;
  158.     print("    ");
  159.     for (i = 0; i < 8; i++) {
  160.         print("+----");
  161.     }
  162.     print("+");
  163.     println("");
  164.     print("    ");
  165.     print("| 0- ");
  166.     print("| 1- ");
  167.     print("| 2- ");
  168.     print("| 3- ");
  169.     print("| 4- ");
  170.     print("| 5- ");
  171.     print("| 6- ");
  172.     print("| 7- ");
  173.     print("|");
  174.     println("");
  175.     print("+---");
  176.     for (i = 0; i < 8; i++) {
  177.         print("+----");
  178.     }
  179.     print("+");
  180.     println("");
  181.     for (i = 0; i < 16; i++) {
  182.         tbuf[0] = '\0';
  183.         convertItoA(sbuf, (long) i, 16);
  184.         strcat(tbuf, "| ");
  185.         strcat(tbuf, sbuf);
  186.         strcat(tbuf, " ");
  187.         for (j = 0; j < 8; j++) {
  188.             if (j*16 + i <= 32) {
  189.                 sprintf(abuf, "| %-3s", asc[j*16 + i]);
  190.             }
  191.             else if (j*16 + i == 127) {
  192.                 sprintf(abuf, "| %-3s", "DEL");
  193.             }
  194.             else {
  195.                 c = (char) (j*16 + i);
  196.                 sprintf(abuf, "| %2c ", c);
  197.             }
  198.             strcat(tbuf, abuf);
  199.         }
  200.         strcat(tbuf, "|");
  201.         println(tbuf);
  202.     }
  203.     print("+---");
  204.     for (i = 0; i < 8; i++) {
  205.         print("+----");
  206.     }
  207.     print("+");
  208.     println("");
  209.     println("");
  210.     for (i = 0; i < 16; i++) {
  211.         sprintf(sbuf, "%-30s",  control[i]);
  212.         sprintf(tbuf, "  %-34s",  control[i+16]);
  213.         print(sbuf);
  214.         println(tbuf);
  215.     }
  216. }
  217. void main(int argc, char *argv[]) {
  218.     if (argc > 1 && strcmp("-h", argv[1]) == 0) {
  219.         printUsage();
  220.         exit(1);
  221.     }
  222.     makeTable();
  223. }




컴파일> cl /GX makeAsciiTableCPP.cpp

실행> makeAsciiTableCPP

    +----+----+----+----+----+----+----+----+
    | 0- | 1- | 2- | 3- | 4- | 5- | 6- | 7- |
+---+----+----+----+----+----+----+----+----+
| 0 | NUL| DLE| Spc|  0 |  @ |  P |  ` |  p |
| 1 | SOH| DC1|  ! |  1 |  A |  Q |  a |  q |
| 2 | STX| DC2|  " |  2 |  B |  R |  b |  r |
| 3 | ETX| DC3|  # |  3 |  C |  S |  c |  s |
| 4 | EOT| DC4|  $ |  4 |  D |  T |  d |  t |
| 5 | ENQ| NAK|  % |  5 |  E |  U |  e |  u |
| 6 | ACK| SYN|  & |  6 |  F |  V |  f |  v |
| 7 | BEL| ETB|  ' |  7 |  G |  W |  g |  w |
| 8 | BS | CAN|  ( |  8 |  H |  X |  h |  x |
| 9 | HT | EM |  ) |  9 |  I |  Y |  i |  y |
| A | LF | SUB|  * |  : |  J |  Z |  j |  z |
| B | VT | ESC|  + |  ; |  K |  [ |  k |  { |
| C | FF | FS |  , |  < |  L |  \ |  l |  | |
| D | CR | GS |  - |  = |  M |  ] |  m |  } |
| E | SO | RS |  . |  > |  N |  ^ |  n |  ~ |
| F | SI | US |  / |  ? |  O |  _ |  o | DEL|
+---+----+----+----+----+----+----+----+----+

NUL (null)                      DLE (data link escape)
SOH (start of heading)          DC1 (device control 1)
STX (start of text)             DC2 (device control 2)
ETX (end of text)               DC3 (device control 3)
EOT (end of transmission)       DC4 (device control 4)
ENQ (enquiry)                   NAK (negative acknowledge)
ACK (acknowledge)               SYN (synchronous idle)
BEL (bell)                      ETB (end of trans. block)
BS  (backspace)                 CAN (cancel)
TAB (horizontal tab)            EM  (end of medium)
LF  (line feed, NL new line)    SUB (substitute, EOF end of file)
VT  (vertical tab)              ESC (escape)
FF  (form feed, NP new page)    FS  (file separator)
CR  (carriage return)           GS  (group separator)
SO  (shift out)                 RS  (record separator)
SI  (shift in)                  US  (unit separator)



Creative Commons License

이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
Posted by Scripter
,

컴퓨터 프로그래밍에서 꼭 알아두어야 할 주요 진법은 당연히 10진법, 2진법, 8진법, 16진법이다.
다음은  0 에서 15 까지의 정수를 10진법, 2진법, 8진법, 16진법의 표로 만들어 보여주는 C++ 소스 코드이다. 진법 변환에 필요한 함수

        convertAtoI(string, radix)
        convertItoA(long, radix)

를 C++ 코드로 자체 작성하여 사용하였다.




  1. /*
  2.  *  Filename: makeRadixTableCPP.cpp
  3.  *            Show the radix table with 10-, 2-, 8-, 16-radices.
  4.  *
  5.  *  Compile: cl /EHsc makeRadixTableCPP.cpp
  6.  *  Execute: makeRadixTable
  7.  *
  8.  *      Date:  2008/03/27
  9.  *    Author:  PH Kim   [ pkim (AT) scripts.pe.kr ]
  10.  */
  11. #include <iostream>
  12. #include <string>
  13. #include <cmath>
  14. using namespace std;
  15. #define MAX_BUF 81
  16. enum { FALSE, TRUE };
  17. void println(char s[]) {
  18.     cout << s << endl;
  19. }
  20. void print(char s[]) {
  21.     cout << s;
  22. }
  23. void printUsage() {
  24.     println("Usage: makeRadixTableCPP");
  25.     println("Show the radix table with 10-, 2-, 8-, 16-radices.");
  26. }
  27. char BASE36[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  28. void convertItoA(char *pstr, long num, int radix) {
  29.     char tmp[2];
  30.     char ret[MAX_BUF];
  31.     char arr[MAX_BUF];
  32.     long q, r;
  33.     int i, n;
  34.     int isNegative = FALSE;
  35.     if (num < 0L) {
  36.         isNegative = TRUE;
  37.         num = -num;
  38.     }
  39.     arr[0] = '\0';
  40.     q = num;
  41.     r = 0L;
  42.     while (q >= (long) radix) {
  43.         r = q % (long) radix;
  44.         q = q / (long) radix;
  45.         tmp[0] = BASE36[r];
  46.         tmp[1] = '\0';
  47.         strcat(arr, tmp);
  48.     }
  49.     tmp[0] = BASE36[q];
  50.     tmp[1] = '\0';
  51.     strcat(arr, tmp);
  52.     if (isNegative) {
  53.         strcat(arr, "-");
  54.     }
  55.     n = strlen(arr);
  56.     for (i = 0; i < n; i++) {
  57.         ret[i] = arr[n - i - 1];
  58.     }
  59.     ret[n] = '\0';
  60.     strcpy(pstr, (char *) ret);
  61. }
  62. long convertAtoI(const char *pstr, int radix) {
  63.     char tmp[2];
  64.     long ret = 0L;
  65.     char arr[MAX_BUF];
  66.     long q, r;
  67.     int isNegative = FALSE;
  68.     int len = strlen(pstr);
  69.     char c;
  70.     int i;
  71.     long val;
  72.     c = pstr[0];
  73.     if (c == '-') {
  74.        isNegative = TRUE;
  75.     }
  76.     else if (c >= '0' && c <= '9') {
  77.         ret = (long) (c - '0');
  78.     }
  79.     else if (c >= 'A' && c <= 'Z') {
  80.         ret = (long) (c - 'A') + 10L;
  81.     }
  82.     else if (c >= 'a' && c <= 'z') {
  83.         ret = (long) (c - 'a') + 10L;
  84.     }
  85.     if (ret >= (long) radix) {
  86.         println("        Invalid character!");
  87.         return ret;
  88.     }
  89.     for (i = 1; i < len; i++) {
  90.         c = pstr[i];
  91.         ret *= radix;
  92.         if (c >= '0' && c <= '9') {
  93.             val = (long) (c - '0');
  94.         }
  95.         else if (c >= 'A' && c <= 'Z') {
  96.             val = (long) (c - 'A') + 10L;
  97.         }
  98.         else if (c >= 'a' && c <= 'z') {
  99.             val = (long) (c - 'a') + 10L;
  100.         }
  101.         if (val >= (long) radix) {
  102.             println("        Invalid character!");
  103.             return ret;
  104.         }
  105.         ret += val;
  106.     }
  107.     return ret;
  108. }
  109. void makeTable() {
  110.     char sbuf[MAX_BUF];
  111.     char abuf[MAX_BUF/2];
  112.     char tbuf[MAX_BUF/2];
  113.     int i;
  114.     for (i = 0; i < 4; i++) {
  115.         print("+-------");
  116.     }
  117.     print("+");
  118.     println("");
  119.     print("|  Dec");
  120.     print("\t|   Bin");
  121.     print("\t|  Oct");
  122.     print("\t|  Hex  |");
  123.     println("");
  124.     for (i = 0; i < 4; i++) {
  125.         print("+-------");
  126.     }
  127.     print("+");
  128.     println("");
  129.     for (i = 0; i < 16; i++) {
  130.         sprintf(sbuf, "|   %2d", i);
  131.         convertItoA((char *)abuf, (long) i, 2);
  132.         sprintf(tbuf, "\t|  %4s", abuf);
  133.         strcat(sbuf, tbuf);
  134.         convertItoA((char *)abuf, (long) i, 8);
  135.         sprintf(tbuf, "\t|   %2s", abuf);
  136.         strcat(sbuf, tbuf);
  137.         convertItoA((char *)abuf, (long) i, 16);
  138.         sprintf(tbuf, "\t|    %-2s |", abuf);
  139.         strcat(sbuf, tbuf);
  140.         println(sbuf);
  141.     }
  142.     for (i = 0; i < 4; i++) {
  143.         print("+-------");
  144.     }
  145.     print("+");
  146.     println("");
  147. }
  148. void main(int argc, char *argv[]) {
  149.     if (argc > 1 && strcmp("-h", argv[1]) == 0) {
  150.         printUsage();
  151.         exit(1);
  152.     }
  153.     makeTable();
  154. }






컴파일> cl /EHsc makeRadixTableCPP.cpp

실행> makeRadixTableCPP

+-------+-------+-------+-------+
|  Dec  |   Bin |  Oct  |  Hex  |
+-------+-------+-------+-------+
|    0  |     0 |    0  |    0  |
|    1  |     1 |    1  |    1  |
|    2  |    10 |    2  |    2  |
|    3  |    11 |    3  |    3  |
|    4  |   100 |    4  |    4  |
|    5  |   101 |    5  |    5  |
|    6  |   110 |    6  |    6  |
|    7  |   111 |    7  |    7  |
|    8  |  1000 |   10  |    8  |
|    9  |  1001 |   11  |    9  |
|   10  |  1010 |   12  |    A  |
|   11  |  1011 |   13  |    B  |
|   12  |  1100 |   14  |    C  |
|   13  |  1101 |   15  |    D  |
|   14  |  1110 |   16  |    E  |
|   15  |  1111 |   17  |    F  |
+-------+-------+-------+-------+





Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.

Posted by Scripter
,

다음은  대화형 모드(interactive mode)에서 진법 변환(radix conversion)하는 C++ 소스 코드이다.
메뉴는 주메뉴 Command: (S)et radix, (A)bout, (Q)uit or E(x)it
와 부메뉴 SubCommand: 'main()' to goto Main menu, 'exit()' or 'quit()' to exit
로 구성되어 있으며, 진법 변환을 하는 핵심 함수 convertAtoI()와 convertItoA()의 소스가 자체 제작되어 포함되어 있다. 이를 이용하는 부분은 157~158째 줄에 있는

         val = convertAtoI(s, srcRdx);
         convertItoA((char *) ret, val, destRdx);

이다. 지원되는 진법은 2진법에서 36진법 까지이다.



  1. /*
  2.  *  Filename: convertRadixCPP.cpp
  3.  *            Convert radix in a interactive mode.
  4.  *
  5.  *  Compile: cl /EHsc convertRadixCPP.cpp
  6.  *  Execute: convertRadixCPP
  7.  *
  8.  *      Date:  2008/03/25
  9.  *    Author:  PH Kim   [ pkim (AT) scripts.pe.kr ]
  10.  */
  11. #include <iostream>
  12. #include <string>
  13. #include <cmath>
  14. using namespace std;
  15. #define MAX_BUF 300
  16. enum { FALSE, TRUE };
  17. struct _TOKEN {
  18.     char a[81];
  19.     char b[81];
  20. };
  21. void println(char s[]) {
  22.     cout << s << endl;
  23. }
  24. void print(char s[]) {
  25.     cout << s;
  26. }
  27. void printUsage() {
  28.     println("Usage: convertRadixCPP");
  29.     println("Convert radix in a interactive mode, where the maximum radix is 36.");
  30. }
  31. void printAbout() {
  32.     println("    About: Convert radix in a interactive mode.");
  33. }
  34. void printMainMenu() {
  35.     println("  Command: (S)etup radix, (A)bout, (Q)uit or E(x)it");
  36. }
  37. void printMainPrompt() {
  38.     print("  Prompt> ");
  39. }
  40. void printSubMenu(int srcRadix, int destRadix) {
  41.     char sbuf[MAX_BUF];
  42.     sprintf(sbuf, "    Convert Radix_%d to Radix_%d", srcRadix, destRadix);
  43.     println(sbuf);
  44.     println("    SubCommand: 'main()' to goto Main menu, 'exit()' or 'quit()' to exit");
  45. }
  46. void printSubPrompt() {
  47.     print("    Input Value>> ");
  48. }
  49. char BASE36[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  50. void convertItoA(char *pstr, long num, int radix) {
  51.    char tmp[2];
  52.    char ret[MAX_BUF];
  53.    char arr[MAX_BUF];
  54.    long q, r;
  55.    int i, n;
  56.    int isNegative = FALSE;
  57.    if (num < 0L) {
  58.       isNegative = TRUE;
  59.       num = -num;
  60.    }
  61.    arr[0] = '\0';
  62.    q = num;
  63.    r = 0L;
  64.    while (q >= (long) radix) {
  65.       r = q % (long) radix;
  66.       q = q / (long) radix;
  67.       tmp[0] = BASE36[r];
  68.       tmp[1] = '\0';
  69.       strcat(arr, tmp);
  70.    }
  71.    tmp[0] = BASE36[q];
  72.    tmp[1] = '\0';
  73.    strcat(arr, tmp);
  74.    if (isNegative) {
  75.       strcat(arr, "-");
  76.    }
  77.     n = strlen(arr);
  78.     for (i = 0; i < n; i++) {
  79.         ret[i] = arr[n - i - 1];
  80.     }
  81.     ret[n] = '\0';
  82.     strcpy(pstr, (char *) ret);
  83. }
  84. long convertAtoI(const char *pstr, int radix) {
  85.     char tmp[2];
  86.     long ret = 0L;
  87.     char arr[MAX_BUF];
  88.     long q, r;
  89.     int isNegative = FALSE;
  90.     int len = strlen(pstr);
  91.     char c;
  92.     int i;
  93.     long val;
  94.     c = pstr[0];
  95.     if (c == '-') {
  96.         isNegative = TRUE;
  97.     }
  98.     else if (c >= '0' && c <= '9') {
  99.         ret = (long) (c - '0');
  100.     }
  101.     else if (c >= 'A' && c <= 'Z') {
  102.         ret = (long) (c - 'A') + 10L;
  103.     }
  104.     else if (c >= 'a' && c <= 'z') {
  105.         ret = (long) (c - 'a') + 10L;
  106.     }
  107.     if (ret >= (long) radix) {
  108.         println("        Invalid character!");
  109.         return ret;
  110.     }
  111.     for (i = 1; i < len; i++) {
  112.         c = pstr[i];
  113.         ret *= radix;
  114.         if (c >= '0' && c <= '9') {
  115.             val = (long) (c - '0');
  116.         }
  117.         else if (c >= 'A' && c <= 'Z') {
  118.             val = (long) (c - 'A') + 10L;
  119.         }
  120.         else if (c >= 'a' && c <= 'z') {
  121.             val = (long) (c - 'a') + 10L;
  122.         }
  123.         if (val >= (long) radix) {
  124.             println("        Invalid character!");
  125.             return ret;
  126.         }
  127.         ret += val;
  128.     }
  129.     return ret;
  130. }
  131. void convertRadix(char *pstr, char s[],  int srcRdx, int destRdx) {
  132.     long val;
  133.     char ret[MAX_BUF];
  134.     val = convertAtoI(s, srcRdx);
  135.     convertItoA((char *) ret, val, destRdx);
  136.     strcpy(pstr, ret);
  137. }
  138. void readLine(char *pdata) {
  139.     scanf("%s", pdata);
  140. }
  141. void readTwo(struct _TOKEN *ptoken) {
  142.     scanf("%s", ptoken->a);
  143.     scanf("%s", ptoken->b);
  144. }
  145. void tokenize(struct _TOKEN *ptoken, const char *line, char c) {
  146.     int len = strlen(line);
  147.     int i;
  148.     int from, to;
  149.     i = 0;
  150.     while (line[i] != c) {
  151.         i++;
  152.     }
  153.     from = i;
  154.     while (line[i] == c) {
  155.         i++;
  156.     }
  157.     to = i;
  158.     strncpy(ptoken->a, line, to - from);
  159.     ptoken->a[to - from] = '\0';
  160.     while (line[i] != c) {
  161.         i++;
  162.     }
  163.     from = i;
  164.     while (line[i] == c) {
  165.         i++;
  166.     }
  167.     to = i;
  168.     strncpy(ptoken->b, line, to - from);
  169.     ptoken->b[to - from] = '\0';
  170. }
  171. void doConvert(int srcRadix, int destRadix) {
  172.     char sbuf[MAX_BUF];
  173.     char line[MAX_BUF];
  174.     char cmd[MAX_BUF];
  175.     char srcStr[MAX_BUF], destStr[MAX_BUF];
  176.     long tmp;
  177.     println("");
  178.     printSubMenu(srcRadix, destRadix);
  179.     do {
  180.         printSubPrompt();
  181.         readLine((char *)cmd);
  182.         while (strlen(cmd) <= 0) {
  183.             readLine((char *)cmd);
  184.         }
  185.         if (strcmp("main()", cmd) == 0) {
  186.             return;
  187.         }
  188.         else if (strcmp("exit()", cmd) == 0 || strcmp("quit()", cmd) == 0) {
  189.             exit(0);
  190.         }
  191.         tmp = convertAtoI(cmd, srcRadix);
  192.         strcpy(srcStr, cmd);
  193.         convertRadix(destStr, srcStr, srcRadix, destRadix);
  194.         sprintf(sbuf, "        ( %s )_%d   --->   ( %s )_%d", srcStr, srcRadix, destStr, destRadix);
  195.         println(sbuf);
  196.         println("");
  197.     } while (TRUE);
  198. }
  199. void doStart() {
  200.     char line[MAX_BUF];
  201.     char cmd[MAX_BUF];
  202.     int srcRadix = 10, destRadix = 10;
  203.     char srcStr[MAX_BUF], destStr[MAX_BUF];
  204.     struct _TOKEN st;
  205.     int onlyOnce = TRUE;
  206.     do {
  207.         println("");
  208.         if (onlyOnce) {
  209.             println("  The supported maximum radix is 36.");
  210.             onlyOnce = FALSE;
  211.         }
  212.         printMainMenu();
  213.         printMainPrompt();
  214.         readLine((char *)cmd);
  215.         while (strlen(cmd) <= 0) {
  216.             readLine((char *)cmd);
  217.         }
  218.         if (strstr("qQxX", cmd) != NULL && strlen(cmd) == 1) {
  219.             exit(0);
  220.         }
  221.         else if (strstr("aA", cmd) != NULL && strlen(cmd) == 1) {
  222.             printAbout();
  223.         }
  224.         else if (strstr("sS", cmd) != NULL && strlen(cmd) == 1) {
  225.             print("  Input the source and target radices (say, 16 2): ");
  226.             readTwo((struct _TOKEN *) &st);
  227.             srcRadix = convertAtoI(st.a, 10);
  228.             destRadix = convertAtoI(st.b, 10);
  229.             doConvert(srcRadix, destRadix);
  230.         }
  231.     } while (TRUE);
  232. }
  233. void main(int argc, char *argv[]) {
  234.     if (argc > 1 && strcmp("-h", argv[1]) == 0) {
  235.         printUsage();
  236.         exit(1);
  237.     }
  238.     doStart();
  239. }




컴파일> cl /EHsc convertRadixCPP.cpp

실행> convertRadixCPP

  The supported maximum radix is 36.
  Command: (S)etup radix, (A)bout, (Q)uit or E(x)it
  Prompt> s
  Input the source and target radices (say, 16 2): 4 2

    Convert Radix_4 to Radix_2
    SubCommand: 'main()' to goto Main menu, 'exit()' or 'quit()' to exit
    Input Value>> 321
        ( 321 )_4   --->   ( 111001 )_2

    Input Value>> main()

  Command: (S)etup radix, (A)bout, (Q)uit or E(x)it
  Prompt> s
  Input the source and target radices (say, 16 2): 2 4

    Convert Radix_2 to Radix_4
    SubCommand: 'main()' to goto Main menu, 'exit()' or 'quit()' to exit
    Input Value>> 111001
        ( 111001 )_2   --->   ( 321 )_4

    Input Value>> quit()





Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.

Posted by Scripter
,

다음은  이차방정식 x^2 - x - 1  = 0 의 양의 근 즉 황금비율(golden ratio)을 구하는 C++ 애플리케이션 소스이다. 황금비율을 구하는 비례방정식은   1 : x = x : (x+1) 이며, 이를 이차방정식으로 표현한 것이 x^2 - x - 1  = 0 이다.

See:  Golden ratio - Sajun.org


  1. /*
  2.  *  Filename: testGoldenRatioCPP.cpp
  3.  *    황금률(즉, 이차방정식 x^2 - x - 1  = 0 의 양의 근)을 계산한다.
  4.  *
  5.  *   Compile: cl -GX testGoldenRatioCPP.cpp
  6.  *
  7.  *   Execute: testGoldenRatioCPP
  8.  *
  9.  *      Date:  2008/03/24
  10.  *    Author:  PH Kim   [ pkim (AT) scripts.pe.kr ]
  11.  */
  12. #include <iostream>
  13. #include <string>
  14. #include <cmath>
  15. using namespace std;
  16. typedef struct _PAIR {
  17.     double x1;
  18.     double x2;
  19. } PAIR;
  20. void printUsing() {
  21.     cout << "Using: testGoldenRatioCPP [-h|-help]" << endl;
  22.     cout << "This calculates the value of the golden ratio." << endl;
  23. }
  24. // 이차방정식 a x^2 + b x + c  = 0 의 근을 구한다.
  25. PAIR *findQuadraticRoot(double a, double b, double c) {
  26.     static PAIR zeros;
  27.     if (a == 0.0) {
  28.         cerr << "Since the highest coefficient is zero, the given equation is not a quadratic equation." << endl;
  29.         exit(1);
  30.     }
  31.     else if (b*b - 4*a*c < 0.0) {
  32.         cerr << "Since the discriminant " << (b*b - 4*a*c) << " is negative, the given equation has no real root." << endl;
  33.         exit(1);
  34.     }
  35.     zeros.x1 = (-b + sqrt(b*b - 4*a*c)) / (2.0 * a);
  36.     zeros.x2 = (-b - sqrt(b*b - 4*a*c)) / (2.0 * a);
  37.     return (PAIR *) &zeros;
  38. }
  39. void main(int argc, char *argv[]) {
  40.     double x1, x2;
  41.     PAIR *values = (PAIR *) findQuadraticRoot(1.0, -1.0, -1.0);
  42.     if (argc > 1 && (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "-help") == 0)) {
  43.         printUsing();
  44.         exit(1);
  45.     }
  46.     values = findQuadraticRoot(1.0, -1.0, -1.0);
  47.     x1 = values->x1;
  48.     x2 = values->x2;
  49.     if (x1 >= x2) {
  50.         cout << "The bigger root is " << x1 << endl;
  51.         cout << "and the less root is " << x2 << endl;
  52.     }
  53.     else {
  54.         cout << "The bigger root is " << x2 << endl;
  55.         cout << "and the less root is " << x1 << endl;
  56.     }
  57. }



컴파일> cl -GX testGoldenRatioCPP.cpp

실행> testGoldenRatioCPP
The bigger root is 1.618034,
and the less root is -0.618034.



Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.

Posted by Scripter
,
현재 시각을 컨솔에 보여주는 간단한 애플리케이션의 C++ 언어 소스 코드이다.
UTC란 1970년 1월 1일 0시 0분 0초를 기준으로 하여 경과된 초 단위의 총 시간을 의미한다.
* UTC(Universal Time  Coordinated, 협정세계시, 協定世界時)


  1. /*
  2.  *  Filename: testCTimeCPP.cpp
  3.  *
  4.  *  Compile: cl -GX testCTimeCPP.cpp
  5.  *
  6.  *  Execute: testCTimeCPP
  7.  */
  8. #include <iostream>
  9. #include <ctime>
  10. using namespace std;
  11. char weekNames[7][3] = {
  12.     "일", "월", "화", "수", "목", "금", "토"
  13. };
  14. int main() {
  15.     time_t timer;
  16.     struct tm *t;
  17.     timer = time(NULL); // 현재 시각을 초 단위로 얻기
  18.     t = localtime(&timer); // 초 단위의 시간을 분리하여 구조체에 넣기
  19.     // 1970년 1월 1일 0시 0분 0초부터 시작하여 현재까지의 초
  20.     cout << "UTC: " << timer << "초" << endl;
  21.     // 현재 시각 표시: 200x년 x월 xx일 (x요일) xx시 xx분 xx초
  22.     cout << (t->tm_year + 1900) << "년 " << (t->tm_mon + 1) << "월 " << t->tm_mday << "일 (" << weekNames[t->tm_wday] << "요일) ";
  23.     cout << t->tm_hour << "시 " << t->tm_min << "분 " << t->tm_sec << "초" << endl;
  24.     // t->tm_yday의 값: 1월 1일은 0, 1월 2일은 1
  25.     cout << "올해 몇 번째 날: " << (1 + t->tm_yday);
  26.     // t->tm_isdst의 값: 0 이면 서머타임 없음
  27.     cout << "서머타임 적용 여부: " << ((t->tm_isdst == 0) ? "안함" : "함") << endl;
  28.     return 0;
  29. }



컴파일> cl testCTimeCPP.cpp

실행> testCTimeCPP
 UTC: 1206323262초
2008년 3월 24일 (월요일) 10시 47분 42초
올해 몇 번째 날: 84서머타임 적용 여부: 안함



Posted by Scripter
,

다음 소스 코드는 http://www.daniweb.com/code/snippet808.html 에서 볼 수 있는 (주어진 범위 안에서) 소수(prime number, 북한 용어로는 씨수) 찾기 C++ 소스 코드이다.
 

  1. # include<iostream.h>
  2. # include<math.h>
  3. void main()
  4. {
  5.     int flag=0;
  6.     unsigned long l, h, temp;
  7.     cout<<"Enter the lower limit:"; cin>>l;
  8.     cout<<"Enter the higher limit:"; cin>>h;
  9.     if(l%2==0)
  10.     {
  11.          if(l==2) cout<<"2\t";
  12.          l++; //taking only odd no
  13.     }
  14.      for(;l<=h;l+=2, flag=0)
  15.      {
  16.           temp=sqrt(l);
  17.           if(temp%2==0) temp++; //taking only odd no
  18.           for(; temp>2; temp--)
  19.          {
  20.              if(l%temp==0)
  21.              {
  22.                  flag=1;
  23.                  break;
  24.               }
  25.          }
  26.          if(flag==0) cout<<l<<"\t";
  27.     }
  28. }

우선 위의 코드를 파이썬 소스 코드 처럼 들여쓰기 규칙을 엄격히 적용하여 아래 처럼 재작성하였다.


  1. #include <iostream.h>
  2. # include <math.h>
  3. void main() {
  4.     int flag = 0;
  5.     unsigned long l, h, temp;
  6.     cout << "Enter the lower limit: ";
  7.     cin >> l;
  8.     cout << "Enter the upper limit: ";
  9.     cin >> h;
  10.     if (l % 2 == 0) {
  11.          if (l == 2)
  12.              cout << "2\t";
  13.          l++;    //  Taking only odd numbers.
  14.     }
  15.     for (; l <= h; l += 2, flag = 0) {
  16.         temp = sqrt(l);
  17.         if (temp % 2 == 0)
  18.            temp++;    //  Taking only odd numbers.
  19.         for (; temp > 2; temp--) {
  20.            if (l % temp == 0) {
  21.                flag = 1;
  22.                break;
  23.            }
  24.        }
  25.        if (flag == 0)
  26.            cout << l << "\t";
  27.     }
  28. }

하지만 아직 표준 C++에 맞지 않으므로 더 고쳐 보았다.

  1. #include <iostream>
  2. #include <cmath>
  3. using namespace std;
  4. void main() {
  5.     int flag = 0;
  6.     unsigned long l, h, temp;
  7.     cout << "Enter the lower limit: ";
  8.     cin >> l;
  9.     cout << "Enter the upper limit: ";
  10.     cin >> h;
  11.     if (l % 2 == 0) {
  12.          if (l == 2)
  13.              cout << "2\t";
  14.          l++;    //  Taking only odd numbers.
  15.     }
  16.     for (; l <= h; l += 2, flag = 0) {
  17.         temp = sqrt(l);
  18.         if (temp % 2 == 0)
  19.            temp++;    //  Taking only odd numbers.
  20.         for (; temp > 2; temp--) {
  21.            if (l % temp == 0) {
  22.                flag = 1;
  23.                break;
  24.            }
  25.        }
  26.        if (flag == 0)
  27.            cout << l << "\t";
  28.     }
  29. }

이제 컴파일도 잘 되고 실행도 잘 될 것이다.
그러나 중요한 것은 알고리즘이다. 즉 소수인지 아닌지 확인하는 과정이 최적화되어 있느냐의 문제이다. 위의 소소 코드에서 27~32째 줄의 for 반복문 부분을 살펴보자,

            for (; temp > 2; temp--) {
               if (l % temp == 0) {
                   flag = 1;
                   break;
               }
          }

예를 들어 l =  3*1999993 = 5999979 인 경우 sqrt(5999979) ≒ 2449.5 이므로,
for 반복문을 시작하면서 temp = 2995 되고 t = 3 이 될 때 까지 무려 1496번을 반복하게 된다.
이 반복문 안의 나눗셈 과정  l % temp 부분을 l % 3 부터 시작하여 l % 5, l % 7, l % 9 ... 이런 식으로 증가시키면서 반복하는 과정으로 진행한다면, l =  3*1999993 = 5999979 인 경우 ㅣ% 3 = 0 이므로 더 이상 반복하지 않고 바로 반복문을 탈출하고 5999979는 소수가 아니라고 판정내린다.

이런 이유로 인하여, 위 소스 코드를 리팩토링하여 다음 처럼 수정하였다.


  1. #include <iostream>
  2. #include <cmath>
  3. using namespace std;
  4. void main() {
  5.     int flag = 0;
  6.     unsigned long l, h, j, temp;
  7.     cout << "Enter the lower limit: ";
  8.     cin >> l;
  9.     cout << "Enter the upper limit: ";
  10.     cin >> h;
  11.     if (l % 2 == 0) {
  12.          if (l == 2)
  13.              cout << "2\t";
  14.          l++;    //  Taking only odd numbers.
  15.     }
  16.     for (; l <= h; l += 2, flag = 0) {
  17.         temp = sqrt(l);
  18.         if (temp % 2 == 0)
  19.            temp++;    //  Taking only odd numbers.
  20.         for (j = 3L; j <= temp; j += 2L) {
  21.            if (l % j == 0L) {
  22.                flag = 1;
  23.                break;
  24.            }
  25.        }
  26.        if (flag == 0)
  27.            cout << l << "\t";
  28.     }
  29. }


 
컴파일> cl /GX findPrimes.cpp

실행> findPrimes
Enter the lower limit: 200
Enter the upper limit: 500
211     223     227     229     233     239     241     251     257     263
269     271     277     281     283     293     307     311     313     317
331     337     347     349     353     359     367     373     379     383
389     397     401     409     419     421     431     433     439     443
449     457     461     463     467     479     487     491     499



Creative Commons License


Posted by Scripter
,
GMP는 The GNU Multiple Precision Arithmetic Library(고정밀도 연산을 위한 GNU 라이브러리)의 줄임글로서 GNU MP라고도 한다. 리눅스 호환 환경이면 대부분 GMP는 이미 설치되어 있을 것이다. GMP의 공식 홈페이지는 http://gmplib.org 이고, GMP는 LGPL 하에서 배포된다.

또 g++는 리눅스 호환 환경에서 쓸 수 있는 C++ 컴파일러(GNU C++ 컴파일러)이다. 대부분의 리눅스 호환 환경에는 g++도 역시 설치되어 있을 것이다.

다음 소스 코드는 GMP의 설치 테스트를 하기 위한 간단한 예제이다.

C 언어에서 GMP 라이브러리를 사용하기 위해서는 헤더 파일 gmp.h를 인클루드 하지만,
C++ 언어에서 GMP 라이브러리를 사용하기 위해서는 헤더 파일 gmpxx.h를 인클루드 한다.

헤더 파일 iostream.h 를 인클루드하고, 이름 공간 std를 사용한 것은 cout 구문을 쓰기 위함이다.
컴파일할 때는 반드시 컴파일 옵션 -lgmpxx -lgmp 을 주어야 한다. (순서도 중요함)
또 컴파일 옵션 -o testGMPXX 을 준 것은 생성될 실행파일명을 testGMPXX로 하라는 의미이다.
이 옵션을 생략하면 생성되는 실행파일명이 a.out(단, cygwin의 경우에는 a.exe)이다.

아래의 소스 코드 중에서

      b = "-5678";

부분은 b가 이미 mpz_class 타입으로 선언되어 있기 때문에 스트링이 mpz_class 타입으로 자동변환하게 된다. 즉, C 언어에서

     mpz_t  b;
     mpz_init_set_str(b, "-5678", 10);

라고 코딩한 것에 해당한다.


  1. /*
  2.  *  Filename:  testGMPXX.cc
  3.  *
  4.  *   Compile:  g++ -o testGMPXX testGMPXX.cc -lgmpxx -lgmp
  5.  *
  6.  *   Execute:  ./testGMPXX
  7.  */
  8. #include <gmpxx.h>
  9. #include <iostream>
  10. using namespace std;
  11. int main (void) {
  12.     mpz_class a, b, c;
  13.     a = 1234;
  14.     b = "-5678";
  15.     c = a + b;
  16.     cout << "sum is " << c << "\n";
  17.     cout << "absolute value is " << abs(c) << "\n";
  18.      return 0;
  19. }



컴파일> g++ -o testGMPXX testGMPXX.cc -lgmpxx -lgmp

실행> ./testGMPXX
sum is -4444
absolute value is 4444




* Visual C++ 9.0 (Visual Studio 2008) 에서 컴파일하기:
컴파일>cl testGMPXX.cpp gmp.lib

실행> testGMPXX
sum is -4444
absolute value is 4444



** 영문  위키피디아에서 소개하는 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 으로 풀어야 한다.
      2) 위의 파일을 받아서 7zip으로 압축 해제하여 libgmpxx-4.dll 을
          C:\MinGW\bin 에 복사힌다.
         (C:\MinGW 은 Luna MinGW 가 설치된 디렉토리이다)

** gcc 버전 확인하기
C:\test\mingw>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++ 버전 확인하기
C:\test\mingw>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)


** Luna MinGW의 GCC 4.5.0 의 g++로 컴파일하기 (소스 파일의 확장명을 cc로 바꾸었다):
C:\test\mingw>g++ -o testGMPXX testGMPXX.cc -lgmpxx -lgmp

C:\test\mingw>testGMPXX
sum is -4444
absolute value is 4444




Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.

Posted by Scripter
,
다항식 p(x) 를 1차 다항식 x - a 로 나눌 때의 몫과 나머지를 구하는 조립제법을
C++ 언어로 구현해 보았다. 조립제법은 일명 Horner의 방법이라고도 불리우는데, 이는
x = a 에서 다항식 p(x)의 값 p(a)을 계산하는 가장 빠른 알고리즘이기도 하다.

         p(x) = (x - a)q(x) + r

여기서 r은 나머지이며 r = p(a) 이다. 또 q(x)는 몫이다.

[참고]
    * 온라인으로 조립제법 표 만들기 손으로 계산하는 조립제법 표 
    * 온라인으로 구하는 다항식의 도함수: 조립제법을 이용한 다항식의 도함수



  1. /*
  2.  *  Filename: testSyntheticDivisionCPP.cpp
  3.  *
  4.  *  Purpose:  Find the quotient and remainder when some polynomial is
  5.  *            divided by a monic polynomial of the first degree.
  6.  *
  7.  *  Compile:  cl -GX testSyntheticDivisionCPP.cpp
  8.  *        Or  cl /EHsc testSyntheticDivisionCPP.cpp
  9.  *
  10.  *  Execute:  testSyntheticDivisionCPP -2 1 3 3 1
  11.  */
  12. #include <iostream>
  13. #include <string>
  14. #include <cmath>
  15. #include <memory>
  16. using namespace std;
  17. void print(char str[]) {
  18.     cout << str;
  19. }
  20. void println() {
  21.     cout << endl;
  22. }
  23. void println(char str[]) {
  24.     cout << str << endl;
  25. }
  26. // 사용법 표시
  27. void printUsage() {
  28.      cout << "사용법: testSyntheticDivisionCPP [수] [피제식의 계수들]" << endl;
  29.      cout << "조립제법(synthetic method)에 의한 다항식 나눗셈 결과를 보여준다." << endl;
  30. }
  31. // 부동소수점수의 표현이 .0 으로 끝나는 경우 이를 잘라낸다.
  32. char *simplify(double v) {
  33.     int n;
  34.     static char t[] = "                               ";
  35.     char tmp[] = "                               ";
  36.     sprintf(t, "%g", v);
  37.     n = strlen(t);
  38.     if ((n > 2) && (t[n - 2] == '.') && (t[n - 1] == '0'))
  39.         t[n-2] = '\0';
  40.     return (char *) t;
  41. }
  42. // 부동소수점수의 표현이 .0 으로 끝나는 경우 이를 잘라낸다.
  43. // 전체 문자열 표시 너비는 매개변수 width 로 전달받아 처리한다.
  44. char *simplify(double v, int width) {
  45.     int n, len;
  46.     static char t[] = "                               ";
  47.     char tmp[] = "                               ";
  48.     sprintf(t, "%g", v);
  49.     n = strlen(t);
  50.     if ((n > 2) && (t[n - 2] == '.') && (t[n - 1] == '0'))
  51.         t[n-2] = '\0';
  52.     len = strlen(t);
  53.     strcpy(tmp, t);
  54.     if (len < width) {
  55.         strncpy(t, "               ", width - len);
  56.         t[width - len] = '\0';
  57.         strcat(t, tmp);
  58.     }
  59.     return (char *) t;
  60. }
  61. // 다항식을 내림차순의 문자열로로 반환하는 함수
  62. // 반환된 문자열은 동적 메모리에 존재하므로.
  63. // 사용 후 반드시 해제(free)하여야 한다.
  64. char *toPolyString(double c[], int size) {
  65.     int SIZE = size;
  66.     int i;
  67.     static char t[300];
  68.     char tmp[80];
  69.     char *pc = simplify(c[0], -1);
  70.     char *pci;
  71.     if (SIZE > 2) {
  72.         if (strlen(pc) == 1 && pc[0] == '1')
  73.             sprintf(t,  "x^%d", SIZE - 1);
  74.         else if (strlen(pc) == 2 && pc[0] == '-' && pc[1] == '1')
  75.             sprintf(t,  "-x^%d", SIZE - 1);
  76.         else
  77.             sprintf(t,  "%s x^%d", simplify(c[0], -1), SIZE - 1);
  78.     }
  79.     else if (SIZE == 2) {
  80.         if (strlen(pc) == 1 && pc[0] == '1')
  81.             strcpy(t,  "x");
  82.         else if (strlen(pc) == 2 && pc[0] == '-' && pc[1] == '1')
  83.             strcpy(t,  "-x");
  84.         else
  85.             sprintf(t,  "%s x", simplify(c[0], -1));
  86.     }
  87.     else if (SIZE == 1) {
  88.         sprintf(t,  "%s", simplify(c[0], -1));
  89.     }
  90.     for (i = 1; i < SIZE; i++) {
  91.         pci = simplify(c[i], -1);
  92.         if (SIZE - 1 - i > 1) {
  93.             if (c[i] > 0.0) {
  94.                 if (strlen(pci) == 1 && pci[0] == '1') {
  95.                     sprintf(tmp,  " + x^%d", SIZE - 1 - i);
  96.                     strcat(t, tmp);
  97.                 }
  98.                 else {
  99.                     sprintf(tmp,  " + %s x^%d", simplify(c[i], -1), SIZE - 1 - i);
  100.                     strcat(t, tmp);
  101.                 }
  102.             }
  103.             else if (c[i] < 0.0) {
  104.                 if (strlen(pci) == 2 && pci[0] == '-' && pci[1] == '1') {
  105.                     sprintf(tmp,  " - x^%d", SIZE - 1 - i);
  106.                     strcat(t, tmp);
  107.                 }
  108.                 else {
  109.                     sprintf(tmp,  " - %s x^%d", simplify(fabs(c[i]), -1), SIZE - 1 - i);
  110.                     strcat(t, tmp);
  111.                 }
  112.             }
  113.         }
  114.         else if (SIZE - 1 - i == 1) {
  115.             if (c[i] > 0.0) {
  116.                 if (strlen(pci) == 1 && pci[0] == '1') {
  117.                     strcat(t, " + x");
  118.                 }
  119.                 else {
  120.                     sprintf(tmp,  " + %s x", simplify(c[i], -1));
  121.                     strcat(t, tmp);
  122.                 }
  123.             }
  124.             else if (c[i] < 0.0) {
  125.                 if (strlen(pci) == 2 && pci[0] == '-' && pci[1] == '1') {
  126.                     strcat(t, " - x");
  127.                 }
  128.                 else {
  129.                     sprintf(tmp,  " - %s x", simplify(fabs(c[i]), -1));
  130.                     strcat(t, tmp);
  131.                 }
  132.             }
  133.         }
  134.         else if (SIZE - 1 - i == 0) {
  135.             if (c[i] > 0.0) {
  136.                 sprintf(tmp,  " + %s", simplify(c[i], -1));
  137.                 strcat(t, tmp);
  138.             }
  139.             else if (c[i] < 0.0) {
  140.                 sprintf(tmp,  " - %s", simplify(fabs(c[i]), -1));
  141.                 strcat(t, tmp);
  142.             }
  143.         }
  144.     }
  145.     return (char *) t;
  146. }
  147. // 다항식 나눗셈 결과를
  148. //     (피제식) = (제식)(몫) + (나마지)
  149. // 형태로 출력
  150. void printDivisionResult(double a, double c[], double b[], int size) {
  151.     int SIZE = size;
  152.     int i;
  153.     double *pTmpPoly;
  154.     double r;
  155.     double monic[] = { 1.0, 0.0 };
  156.     print("  ");
  157.     print(toPolyString(c, SIZE));
  158.     println("");
  159.     print("    = ( ");
  160.     monic[1] = -a;
  161.     print(toPolyString(  monic, 2 ));
  162.     print(" )");
  163.     pTmpPoly = (double *)  calloc(SIZE - 1, sizeof(double));
  164.     for (i = 0; i < SIZE - 1; i++) {
  165.         pTmpPoly[i] = b[i];
  166.     }
  167.     print("( ");
  168.     print(toPolyString(pTmpPoly, SIZE - 1));
  169.     print(" )");
  170.     free(pTmpPoly);
  171.     r = b[SIZE - 1];
  172.     if (r > 0.0) {
  173.         print(" + ");
  174.         print(simplify(r, -1));
  175.     }
  176.     else if (r < 0.0) {
  177.         print(" - ");
  178.         print(simplify(fabs(r), -1));
  179.     }
  180.     println();
  181. }
  182. // 조립제법 계산표 출력 함수
  183. void printSyntheticTable(double a, double c[], double s[], double q[], int size) {
  184.     int SIZE = size;
  185.     int i;
  186.     print("       | ");
  187.     print(simplify(c[0], 6));
  188.     for (i = 1; i < SIZE; i++) {
  189.         print("  ");
  190.         print(simplify(c[i], 6));
  191.     }
  192.     println();
  193.     print(simplify(a, 6));
  194.     print(" | ");
  195.     print("        ");
  196.     print(simplify(s[1], 6));
  197.     for (i = 2; i < SIZE; i++) {
  198.         print("  ");
  199.         print(simplify(s[i], 6));
  200.     }
  201.     println();
  202.     print("       |-");
  203.     for (i = 0; i < SIZE; i++) {
  204.         print("--------");
  205.     }
  206.     println();
  207.     print("         ");
  208.     print(simplify(q[0], 6));
  209.     for (i = 1; i < SIZE; i++) {
  210.         print("  ");
  211.         print(simplify(q[i], 6));
  212.     }
  213.     println();
  214. }
  215. // C++ 언어의 실행 시작 지점
  216. int main(int argc, char *argv[]) {
  217.     int i;
  218.     int SIZE = argc - 2;
  219.     double a, c[15], s[15], b[15];
  220.     if (argc < 4) {
  221.         printUsage();
  222.         exit(1);
  223.     }
  224.     //////////////////////////////////////////////////////
  225.     // 피제식은 c_0 x^n +  c_1 x^(n -1) + ... + c_n
  226.     // 제식은 x -  a
  227.     a = atof(argv[1]);
  228.     for (i = 0; i < SIZE; i++) {
  229.      c[i] = atof(argv[i + 2]);
  230.     }
  231.     //////////////////////////////////////////////////////
  232.     // 조립제법의 주요 부분
  233.     s[0] = 0.0;
  234.     b[0] = c[0];
  235.     for (i = 1; i < SIZE; i++) {
  236.         s[i] = b[i-1]*a;
  237.         b[i] = c[i] + s[i];
  238.     }
  239.     print("몫의 계수는 ");
  240.     for (i = 0; i < SIZE - 2; i++) {
  241.         print(simplify(b[i], -1));
  242.         print(", ");
  243.     }
  244.     print(simplify(b[SIZE - 2], -1));
  245.     print(" 이고, 나머지는 ");
  246.     print(simplify(b[SIZE - 1], -1));
  247.     println(" 이다.");
  248.     println();
  249.     //////////////////////////////////////////////////////
  250.     // 조립제법 표를 출력한다.
  251.     printSyntheticTable(a, c, s, b, SIZE);
  252.     println();
  253.     //////////////////////////////////////////////////////
  254.     // (피제식) = (제식) x (몫) + (나머지)
  255.     printDivisionResult(a, c, b, SIZE);
  256.     return 0;
  257. }




컴파일> cl -EHsc testSyntheticDivisionCPP.cpp

실행> testSyntheticDivisionCPP 1 2 3 4 5
몫의 계수는 2, 5, 9 이고, 나머지는 14 이다.

       |      2       3       4       5
     1 |              2       5       9
       |---------------------------------
              2       5       9      14

  2 x^3 + 3 x^2 + 4 x + 5
    = ( x - 1 )( 2 x^2 + 5 x + 9 ) + 14



Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
Posted by Scripter
,