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

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

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

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

<gsl/gsl_math.h> 를 인클루드하면 gsl_math.h 가 자체적으로 <math.h> 를 또 인클루드하므로, <math.h> 를 별도로 인크루드할 필요가 없다.

sinh 와 cosh 의 역함수로 그냥 C 언어의 <math.h> 에서 정의된 asinhacosh 를 써도 되지만. 여기서는 <gsl/gsl_math.h> 에서 정의된 gsl_asinhgsl_acosh 를 써 보았다.

참고로 gsl 이라 함은 GNU Scientific Library 의 줄임글이다.

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

/*
 * Filename: testArcSineWithGSL.c
 *
 *    Require gsl 1.13 above and Visual C 2010
 *
 *     Or
 *
 *    Require gsl 1.13 above and Cygwin
 *
 * Compile: cl testArcSineWithGSL.c gsl.lib /MD
 * Execute: testArcSineWithGSL
 *
 *  Or
 *
 * Compile: gcc -Wall -I/usr/local/include -c testArcSineWithGSL.c
 *     Link: gcc -o testArcSineGSL -L/usr/local/lib testArcSineWithGSL.o -lgsl
 * Execute: ./testArcSineGSL
 *
 *
 * Date: 2013. 1. 10.
 * Copyright (c) pkim _AT_ scripts.pe.kr
 */

#include <stdio.h>
#include <gsl/gsl_math.h>   // This includes <math.h>


int main(void) {
    double x, y, u, v;

    x = -0.9;
    y = asin(x);
    printf("x = %g\n", x);
    printf("y = asin(%g) = %.9f\n", x, y);
    printf("sin(%.9f) = %g\n", y, sin(y));
    printf("\n");

    x = 1.1;
    u = gsl_acosh(x);
    v = gsl_asinh(x);
    printf("x = %g\n", x);
    printf("u = gsl_acosh(%g) = %.10f\n", x, u);
    printf("v = gsl_asinh(%g) = %.10f\n", x, v);
    printf("\n");

    printf("cosh(u) = cosh(%.10f) = %g\n", u, cosh(u));
    printf("sinh(v) = sinh(%.10f) = %g\n", v, sinh(v));

    return 0;
}

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

x = 1.1
u = gsl_acosh(1.1) = 0.4435682544
v = gsl_asinh(1.1) = 0.9503469298

cosh(u) = cosh(0.4435682544) = 1.1
sinh(v) = sinh(0.9503469298) = 1.1

*/

 

 

Posted by Scripter
,

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

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

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

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

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

/*
 * Filename: testArcSine.c
 *
 * Compile: cl testArcSine.c
 * Execute: testArcSine
 *
 *  Or
 *
 * Cpmpile: gcc -o testArcSine testArcSine.c
 * Execute: ./testArcSine
 *
 * Date: 2013. 1. 1.
 * Copyright (c) pkim _AT_ scripts.pe.kr
 */

#include <stdio.h>
#include <math.h>

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() {

    double u, v;
    double x = -0.9;
    double y = asin(x);

    printf("y = asin(%g) = %.9f\n", x,  y);
    printf("sin(y) = sin(%.9f) = %g\n", y, sin(y));
    printf("\n");

    x = 1.1;
    u = acosh(x);
    printf("u = acosh(%g) = %.10f\n", x,  u);

    v = asinh(x);
    printf("v = asinh(%g) = %.10f\n", x, v);

    printf("cosh(u) = cosh(%.10f) = %g\n", u, cosh(u));
    printf("sinh(v) = sinh(%.10f) = %g\n", v, sinh(v));

    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
,

Lanczos 알고리즘은 Stirling 공식에 의한 알고리즘 보다 정밀하며, 십진수로 유효숫자 약 15자리 까지는 정확하게 계산해 준다. 단지 exp 함수를 이용하는 부분에서는 exp, sin, pow 함수들의 구현에 따라 오차가 더 있을 수 있다. 소스를 보면 (조금이라도 유효수자의 개수가 더 많은 계산을 하기 위해) double 타입이 아니라 long double 타입으로 처리하고 있음을 알 수 있다.

            long double frac(long double x)

            long double gamma2(long double y)

Unix/Linux의 C 컴파일러 gcc 를 사용하면 math 라이브러리에 tgamma 라는 함수가 이미 있다. 이 함수와 (자체 구현된) gamma2 함수에 의한 계산 결과를 비교하기 바란다.


// Filename: testLanczos-02.c
//
// Compile: gcc -o testLanczos-02 -lm testLanczos-02.c
// Execute: ./testLanczos-02
// Output:
//      Gamma(10) = (9)! = 362880
//     tgamma(10) = (9)! = 362880
//
// See: http://www.thinbasic.com/community/showthread.php?11279-Gamma-function
// See: http://en.wikipedia.org/wiki/Gamma_function
// See: http://http://jany.tistory.com/53
// See: http://support.realsoftware.com/listarchives/realbasic-nug/2003-08/msg03123.html

#include <stdio.h>
#include <math.h>

long double frac(long double x)
{
  long double result;

  if (x >= 0.0)
      result = fabs(x) - floor(x);
  else
      result = -(fabs(x) - floor(x));
  return result;
}

long double gamma2(long double y)
{
        long double pi = 3.1415926535897932385;
        long double sq2pi = 2.50662827463100050241577;  // sqrt(2Pi)
        long double g = 607./128;   // best resu'ts when 4<=g<=5
        long double t, w, gam, x = y - 1.0;
        int i, cg = 14;
        long double c[16];
        
        // Lanczos approximation for the complex plane
        // calculated using vpa digits(256)
        // the best set of coeffs was selected from
        // a solution space of g=0 to 32 with 1 to 32 terms
        // these coeffs really give superb performance
        // of 15 sig. digits for 0<=real(z)<=171
        // coeffs should sum to about g*g/2+23/24
        
        // http://www.numericana.com/answer/info/godfrey.htm
        
          c[ 1] =        0.99999999999999709182;   // thiBasic arrays start at 1 ?
          c[ 2] =       57.156235665862923517;
          c[ 3] =      -59.597960355475491248;
          c[ 4] =       14.136097974741747174;
          c[ 5] =       -0.49191381609762019978;
          c[ 6] =        0.33994649984811888699/10000;
          c[ 7] =        0.46523628927048575665/10000;
          c[ 8] =       -0.98374475304879564677/10000;
          c[ 9] =        0.15808870322491248884/1000;
          c[10] =       -0.21026444172410488319/1000;
          c[11] =        0.21743961811521264320/1000;
          c[12] =       -0.16431810653676389022/1000;
          c[13] =        0.84418223983852743293/10000;
          c[14] =       -0.26190838401581408670/10000;
          c[15] =        0.36899182659531622704/100000;
          
        // printf(" y = %LG\n", y);
       //  printf(" x = %LG\n", x);

        if ( x < 0.0 ) {
            x = -x;
            if (frac(x) == 0.0) {
                gam = pow(10.0, 4932);
            }
            else {
                t = c[1];
                for (i = 1; i <= cg; i++) {
                    t = t + c[i+1]/(x+i);
                }
                w = x + g + 0.5;
                gam = pow(w, x+0.5)*exp(-w)*sq2pi*t;
                gam = pi*x/(gam*sin(pi*x));
            }
        }
        else {
            t = c[1];
            for (i = 1; i <= cg; i++) {
                t = t + c[i+1]/(x+i);
            }
            w = x + g + 0.5;
            // printf("   w = %LG\n", w);
            gam = pow(w, x+0.5)*exp(-w)*sq2pi*t;
        }
        return gam;
 }

int main()
{
    long double y, x = 1.0;
    while (x > 0) {
        printf("Input x(0 to exit): ");
        scanf("%LF", &x);
        // printf("x = %LG\n", x);
        if (x == 0.0) {
            break;
        }
        y = gamma2(x);
        printf(" Gamma(%LG) = (%LG)! = %30LF\n", x, x - 1, y);
        printf("tgamma(%LG) = (%LG)! = %30lf\n", x, x - 1, tgamma(x));
    }
    // printf("All done. Press any key to finish\n");
    return 0;
}

/*
100! =  93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000

Execute: ./testLanczos-02
Result:
Input x(0 to exit): 101
 Gamma(101) = (100)! = 93326215443944119652178484825626229006662095017918287040779978859652504703806235528941436474245838774007726779438736471616107541007146050712395913562333118464.000000
tgamma(101) = (100)! = 93326215443947553183793338240612302366006877769275129529769934567734921397913148008797092443225880267680360266584467988186500321788890593731926090238149001216.000000
Input x(0 to exit): 0
*/





Posted by Scripter
,

우선 위키피디아에서 소개하는 MPFR의 설명을 보자

GNU MPFR (for GNU Multiple Precision Floating-Point Reliably[1]) is a portable C library for arbitrary-precision binary floating-point computation with correct rounding, based on GNU Multi-Precision Library.

 

  또 다음은 MPFR 홈페이지에서 소개하는 MPFR의 의미이다.

The main goal of MPFR is to provide a library for multiple-precision floating-point computation which is both efficient and has a well-defined semantics. It copies the good ideas from the ANSI/IEEE-754 standard for double-precision floating-point arithmetic (53-bit significand).

 

GMP는 자리수가 긴 정수 계산을 하기 위한 라이브러리이지만, MPFR은 (IEEE-754의 한계를 넘어) 소소점 이하의 자리수를 원하는 만큼 충분히 확보하여 (유효숫자의 길이가 매우 긴) 소수점수를 계산하기 위한 라이브러리이다.


MPFR을 설치하자면 먼저 GMP가 설치되어 있어야 한다. MPFR의 현재 안정 버전은 3.1,0(2011년 10월 3일 출시)이다. MPFR을 설치하기 위해 GMP 4.1.0 이상이면 되지만, 가급적 GMP 4.2.3 이상을 추천한다. 

MPFR 소스의 압축파일을 내려받아서 압축 해제하고, 그 해제된 디렉로리로 가서

       $ ./configure --prefix=설치될경로 --with-gmp=이미설치된GMP리이브러리의경로

       (예: ./configure --prefix=/usr/local --with-gmp=/usr/local )

       (다른 예: ./configure --prefix=/usr/local --with-gmp-lib=/usr/local/lib --with-gmp-include=/usr/local/include )

       $ make 

       $ make check

       $ sudo make install

의 순서로 설치한다.


다음 소스 코드는 MPFR의 설치 테스트를 하기 위한 간단한 예제(오일러의 초월수 e를 계산하는 예제)이다.

C 언어에서 MPFR 라이브러리를 사용하기 위해서는 헤더 파일 gmp.h와 mpfr.h를 인클루드한다.
컴파일할 때는 반드시 컴파일 옵션 -lmpfr(또는 -lmpfr -lgmp)를 주어야 한다.
또 컴파일 옵션 -o testMPFR 을 준 것은 생성될 실행파일명을 testMPFR로 하라는 의미이다.
이 옵션을 생략하면 생성되는 실행파일명이 a.out(단, cygwin의 경우에는 a.exe)이다.

mpfr_set_d 함수는 mpfr_t 타입의 소수점수에 double 타입의 부동소수점수를 대입하는 함수이고,
mpfr_mul_ui 함수는 mpfr_t 타입의 소수점수에 unsigned long 타입의 정수를 곱하여 대입하는 함수이고,
mpfr_add 함수는 mpfr_t 타입의 소수점수에 mpfr_t 타입의 소수점수를 합아려 대입하는 함수이고,
mpfr_div 함수는 mpfr_t 타입의 소수점수에 mpfr_t 타입의 소수점수를 나누어 대입하는 함수이다.

mpfr_init2 함수는 mpfr_t 타입의 소수점수 변수를 초기화 하는 함수이다. (초기화된 값은 0.0)

       mpfr_init2(t, 200);

또 mpfr_out_str 함수는 첫번째 인수에 지정된 출력장치에 주어진 ASCIZ 문자열을 두번째 인수에 주어진 적당한 진법(이 예에서는 10)을 적용하여 네번째 인수에 주어진 mpfr_t 타입의 소수점수(이 예에서는 s)를 출력하는 함수이다.


  1. // Filename: testMPFR.c
  2. //
  3. //     See: http://www.mpfr.org/sample.html
  4. //
  5. // Compile: gcc -o testMPFR testMPFR.c -lmpfr
  6. //      Or: gcc -o testMPFR testMPFR.c -lmpfr -lgmp
  7. // ExecuteL ./testMPFR
  8. #include <stdio.h>
  9. #include <gmp.h>
  10. #include <mpfr.h>
  11. int main (void)
  12. {
  13.   unsigned int i;
  14.   mpfr_t s, t, u;
  15.   mpfr_init2 (t, 200);
  16.   mpfr_set_d (t, 1.0, GMP_RNDD);
  17.   mpfr_init2 (s, 200);
  18.   mpfr_set_d (s, 1.0, GMP_RNDD);
  19.   mpfr_init2 (u, 200);
  20.   for (i = 1; i <= 100; i++)
  21.     {
  22.       mpfr_mul_ui (t, t, i, GMP_RNDU);
  23.       mpfr_set_d (u, 1.0, GMP_RNDD);
  24.       mpfr_div (u, u, t, GMP_RNDD);
  25.       mpfr_add (s, s, u, GMP_RNDD);
  26.     }
  27.   printf ("Sum is ");
  28.   mpfr_out_str (stdout, 10, 0, s, GMP_RNDD);
  29.   putchar ('\n');
  30.   mpfr_clear (s);
  31.   mpfr_clear (t);
  32.   mpfr_clear (u);
  33.   return 0;
  34. }
  35. /*
  36. Output:
  37. Sum is 2.7182818284590452353602874713526624977572470936999595749669131
  38. */


컴파일> gcc -o testMPFR testMPFR.c -lmpfr -lgmp

실행> ./testMPFR
2.7182818284590452353602874713526624977572470936999595749669131




Posted by Scripter
,

C 언어에서 long long 타입은 (부호가 있는) 64비트 정수 타입입니다.

win32 환경이라도 long long 타입을 C 언어에서 쓸 수 있습니다.

아래의 소스는

    Visual C++ 2010 Express

    Dev-C++

    LCC 컴파일러  또는  LCC-win32 컴파일러

   GCC 컴파일러

   TCC (Tiny-CC) 컴파일러

중 하나면 컴파일하여 실행시킬 수 있습니다.

 

TCC 로는 -run 옵션을 사용하여

    프롬프트>   tcc -run testLongLong.c

하면 (실행 파일 만들지 않고) 소스를 직접 실행시킬 수 있습니다.

 

 

// Filename: testLongLong_001.c
//
// Compile & Link: gcc -o  testComplexISOC99_002  testLongLong_001.c
// Execute: ./tesLongLong_001
//
// Or
//
// Compile & Link: cl testLongLong_001.c
// Execute: testLongLong_001
//
// Or
//
// Compile & Link: lc testLongLong_001.c
// Execute: testLongLong_001
//
// Or
//
// Compile: lcc -o testLongLong_001.obj testLongLong_001.c
// Link: lcclnk testLongLong_001.obj
// Execute: tesLongLong_001


#include <stdio.h>
#include <string.h>

int main(int argc, char** argv)
{
 long long a = 1000000000L;
 long long b = 1000000000L;
 char buf[100];

    printf("a * b = %lld * %lld = %lld\n", a, b, a*b);

    sprintf(buf, "%lld", a*b);
    printf("strlen(a * b) = strlen(%lld) = %d\n", a*b, strlen(buf));

    return 0;
}

/*
-------------------
Result of execution:
-------------------
a * b = 1000000000 * 1000000000 = 1000000000000000000
strlen(a * b) = strlen(1000000000000000000) = 19
*/

 

 

 

Posted by Scripter
,

 

컴파일은 ANSI/ISOC99 를 (대부분) 지원하는 C 컴파일러 

         GCC 컴파일러 또는 LCC 컴파일러 (또는 기타 컴파일러)

를 쓰면 됩니다.

Visual C++ 2010 은 ANSI/ISOC99 를 지원하지 않습니다.

[참고] ANSI/ISOC99 (Wikipedia)

 

// Filename: testComplexISOC99.c
//
// Compile & Link: gcc -o  testComplexISOC99  testComplexISOC99.c
// Execute: ./testComplexISOC99
//
// Or
//
// Compile & Link: lc testComplexISOC99.c
// Execute: testComplexISOC99
//
// Or
//
// Compile: lcc -o testComplexISOC99.obj testComplexISOC99.c
// Link: lcclnk testComplexISOC99.obj
// Execute: testComplexISOC99


#include <stdio.h>
#include <complex.h>

int main(int argc, char** argv)
{
 float complex z1 = 3.0 + 4.0i;
 float complex z2 = 2.0 - 1.0i;
 float complex z3 = z1 + z2;
 float complex z4 = z1 - z2;
 float complex z5 = z1 * z2;
 float complex z6 = z1 / z2;
 float complex z7 = conjf(z1);
 // float arg = cargf(z1);
 float arg = carg(z1);     // for :CC-win32

    printf("z1 = %f + %fj\n", crealf(z1), cimagf(z1));
    printf("z2 = %f + %fj\n", crealf(z2), cimagf(z2));
    printf("So,\n");
    printf("z3 = z1 + z2 = %f + %fj\n", crealf(z3), cimagf(z3));
    printf("z4 = z1 - z2 = %f + %fj\n", crealf(z4), cimagf(z4));
    printf("z5 = z1 * z2 = %f + %fj\n", crealf(z5), cimagf(z5));
    printf("z6 = z1 / z2 = %f + %fj\n", crealf(z6), cimagf(z6));

    printf("z7 = conjf(z1) = %f + %fj\n", crealf(z7), cimagf(z7));
    // printf("arg = cargf(z1) = %f\n", arg);
    printf("arg = carg(z1) = %f\n", arg);  // for LCC-win32

    return 0;
}

/*
-------------------
Result of execution:
-------------------
z1 = 3.000000 + 4.000000j
z2 = 2.000000 + 1.000000j
So,
z3 = z1 + z2 = 5.000000 + 5.000000j
z4 = z1 - z2 = 1.000000 + 3.000000j
z5 = z1 * z2 = 2.000000 + 11.000000j
z6 = z1 / z2 = 2.000000 + 1.000000j
z7 = conjf(z1) = 3.000000 + -4.000000j
arg = carg(z1) = 0.927295
*/

 

 

 

Posted by Scripter
,

아래의 소스는 윈도우에서

            Luna MinGW & GNU C 4.5.0 (gcc), 

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


* 소스 파일명: recFactGMP01.c

/*
 *  Filename: recFactGMP01.c
 *
 *  Compile: gcc -o recFactGMP01 recFactGMP01.c -lgmp
 */

#include <stdio.h>
#include <gmp.h>

void factorial(mpz_t v, int n) {
 int i;
    mpz_t t;
    mpz_init (t);
    mpz_init_set_str (v, "1", 0);
    for (i = 1; i <= n; i++) {
        mpz_init_set_si (t, i);
        mpz_mul(v, v, t);
    }
}

int main(int argc, char *argv[]) {
    int n1 = 9;
    int n2 = 30;
    int i;
    mpz_t v;
    mpz_init (v);
    for (i = n1; i <= n2; i++) {
        mpz_init_set_si (v, 1);
        factorial(v, i);
        gmp_printf("%d! = %Zd\n", i, v);
        if (i == 13)
        printf("-- below calc are regular ----\n");
    }
    return 0;
}



실행 결과:
프롬프트> recFactGMP01
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
,

아래의 소스는

            Visual Studio 2010 Express (Visual C++ 10.0),
            MinGW & GNU C 3.4.5 (gcc), 

로 테스트되었다. long 타입의 한계로 인하여 13! 까지만 정확히 계산되었다.

* 소스 파일명: recursiveFactorial.c

#include <stdio.h>

long recFacto(long y, int k, int n) {
    if (n <= 1)
        return 1L;
    else if (k == n)
        return y;
    return recFacto(y*(k+1), k+1, n);
}

long factorial(int n) {
    return recFacto(1L, 1, n);
}

int main(int argc, char *argv[]) {
    int n = 20;
    int i;
    for (i = 0; i <= n; i++) {
        printf("%d! = %ld\n", i, factorial(i));
        if (i == 13)
         printf("-- below calc are fault ----\n");
    }
}




실행 결과:
프롬프트> recursiveFactorial
0! = 1
1! = 1
2! = 2
3! = 6
4! = 24
5! = 120
6! = 720
7! = 5040
8! = 40320
9! = 362880
10! = 3628800
11! = 39916800
12! = 479001600
13! = 1932053504
-- below calc are fault ----
14! = 1278945280
15! = 2004310016
16! = 2004189184
17! = -288522240
18! = -898433024
19! = 109641728
20! = -2102132736



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

 

Posted by Scripter
,


[파일명:  testSort.c]------------------------------------------------
#include <stdio.h>
#include <string.h>

char SBUF[20][80];
char TBUF[80];

void quickSort(char array[20][80], int start, int end);
void swap(char array[20][80], int x, int y);
void printArray(char array[20][80], int start, int end);
void exit(int n);

int main(int argc, char* argv[]) {
    char* pbuf;
    int i;
    if (argc > 1 && argc < 22) {
        for (i = 0; i < argc - 1; i++) {
            if (strlen(argv[i+1]) > 79) {
                printf("Caught: strlen(\"%s\") = %d, which is too long.\n", argv[i+1], strlen(argv[i+1]));
                exit(1);
            }
            sprintf(SBUF[i], argv[i+1]);
        }
        quickSort(&SBUF[0], 0, argc - 2);
        printArray(SBUF, 0, argc - 2);
    }
    else if (argc > 21) {
        printf("Given too many items. (The counter of items should be less then 20.)\n");
        exit(1);
    }
    return 0;
}

void quickSort(char array[20][80], int start, int end) {
    int i = start;
    int k = end;
    char pivot[80];

    if (end - start >= 1) {
        strcpy(pivot, array[start]);
        while (k > i) {
            while (strcmp(array[i], pivot) <= 0 && i <= end && k > i)
                i++;
            while (strcmp(array[k], pivot) > 0 && k >= start && k >= i)
                k--;
            if (k > i) {
                swap(array, i, k);
            }
        }
        swap(array, start, k);

        quickSort(array, start, k - 1);
        quickSort(array, k + 1, end);
    }
    else {
        return;
    }
}

void swap(char array[20][80], int x, int y) {
     strcpy(TBUF, array[x]);
     strcpy(array[x], array[y]);
     strcpy(array[y], TBUF);
}

void printArray(char array[20][80], int start, int end) {
    int i;
    printf("[");
    for (i = start; i < end; i++) {
        printf("%s, ", array[i]);
    }
    if (end >= start)
        printf("%s", array[end]);
    printf("]\n");
}
------------------------------------------------


컴파일> cl testSort.c
또는
컴파일> bcc32 testSort.c
또는
컴파일> gcc -o testSort testSort.c

실행> testSort 하나 둘 셋 넷
[넷, 둘, 셋, 하나]

실행> ./testSort one two thee four
[four, one, three, two]


 

Posted by Scripter
,


초등학교 때 배우는 두 정수의 곱셈표를 만들어 주는 C 소스이다.

/*
 * Filename: makeMultTable.c
 *
 *     Print a multiplication table.
 *
 *     Compile: cl makeMultTable.c
 *     Execute: makeMultTable 230 5100
 *
 * Date: 2009/03/06
 * Author: pkim (AT) scripts.pe.kr
 */

#include <stdio.h>
#include <string.h>
#include <math.h>

void printUsing();
void printMultTable(int x, int y);

int main(int argc, char *argv[]) {
    long x, y;
    if (argc >= 3) {
        x = atoi(argv[1]);
        y = atoi(argv[2]);
        printf("\n");
        printMultTable(x, y);
    }
    else {
        printUsing();
   }
    return 0;
}

void printUsing() {
    printf("Using: makeMultTable [number1] [number2]\n");
    printf("Print a multiplication table for the given two integers.\n");
}

void printMultTable(long x, long y) {
    long nx, ny;
    long z;
    int ntail1;
    int ntail2;
    int n;
    int y1;
    int i;
    char strX[80];
    char strY[80];
    char strZ[80];
    char strT[80];
    char zeros[80];
    char whites[80];
    char bars[80];
    char line1[80];
    char line2[80];
    char line3[80];
    char line4[80];
    char loffset[20];
    char buf[80];

    nx = (x >= 0) ? x : - x;
    ny = (y >= 0) ? y : - y;
    ntail1 = 0;
    ntail2 = 0;
    while (nx % 10L == 0L) {
        nx = nx / 10L;
        ntail1++;
    }
    while (ny % 10L == 0L) {
        ny = ny / 10L;
        ntail2++;
    }
    z = nx * ny;
    sprintf(strZ, "%ld", z);
    sprintf(strX, "%ld", nx);
    sprintf(strY, "%ld", ny);
    n = strlen(strY);
    strcpy(zeros, "0000000000000000000000000000000000000000");
    strcpy(whites, "                                        ");
    strcpy(bars, "----------------------------------------");
    strcpy(loffset, "       ");
    sprintf(line4, "%s%ld", loffset, nx*ny);
    strncpy(buf, zeros, ntail1 + ntail2);
    buf[ntail1 + ntail2] = '\0';
    strcat(line4, buf);
    strcpy(line1, loffset);
    strncpy(buf, whites, strlen(strZ) - strlen(strX));
    buf[strlen(strZ) - strlen(strX)] = '\0';
    strcat(buf, strX);
    strcat(line1, buf);
    strncpy(buf, zeros, ntail1);
    buf[ntail1] = '\0';
    strcat(line1, buf);

    strcpy(line2, "   x ) ");
    strncpy(buf, whites, strlen(strZ) - strlen(strY));
    buf[strlen(strZ) - strlen(strY)] = '\0';
    strcat(buf, strY);
    strcat(line2, buf);
    strncpy(buf, zeros, ntail2);
    buf[ntail2] = '\0';
    strcat(line2, buf);

    strcpy(line3, "     --");
    strncpy(buf, bars, strlen(strZ));
    buf[strlen(strZ)] = '\0';
    strcat(line3, buf);

    printf("%s\n", line1);
    printf("%s\n", line2);
    printf("%s\n", line3);
    if (strlen(strY) > 1) {
        for (i = 0; i < strlen(strY); i++) {
         buf[0] = strY[strlen(strY) - i - 1];
         buf[1] = '\0';
            y1 = atoi(buf);
            if (y1 != 0) {
                sprintf(strT, "%ld", nx * y1);
                strcpy(line2, loffset);
                strncpy(buf, whites, strlen(strZ) - strlen(strT) - i);
                buf[strlen(strZ) - strlen(strT) - i] = '\0';
                strcat(buf, strT);
                strcat(line2, buf);
                printf("%s\n", line2);
            }
        }
        printf("%s\n", line3);
    }
    printf("%s\n", line4);
}





컴파일> cl makeMultTable.c
실행> makeMultTable 230 5100
결과>

          230
   x )   5100
     ------
         23
       115
     ------
       1173000

 

 


Posted by Scripter
,