Julia 언어 소스:

##  Filename: testHexView_02.jl
##
##  Purpose:  Show the hexadecimal codes of the given binary file.
##
##  Set Env: set path=d:\julia;%path%
##  Execute: julia testHexView_02.jl [filename]
##
##      Date:  2013. 8. 4.

function printUsage()
    @printf("Using: julia testHexView_02.jl [filename]\n")
end

function toHex(b)
    s = ""
    x1 = (b & 0xF0) >> 4
    x2 = b & 0x0F
    if x1 > 9
        s = s * char(int('A') + (x1 - 10))
    else
        s = s * char(int('0') + x1)
    end
    if x2 > 9
        s = s * char(int('A') + (x2 - 10))
    else
        s = s * char(int('0') + x2)
    end
    return s
end


function toHex8(n)
    s = "" 
    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
    s = "0"
    if x2 < 10
        s = s * char(int('0') + x2)
    else
        s = s * char(int('A') + (x2 - 10))
    end
    if x3 < 10
        s = s * char(int('0') + x3)
    else
        s = s * char(int('A') + (x3 - 10))
    end
    if x4 < 10
        s = s * char(int('0') + x4)
    else
        s = s * char(int('A') + (x4 - 10))
    end
        s = s * " "
    if x5 < 10
        s = s * char(int('0') + x5)
    else
        s = s * char(int('A') + (x5 - 10))
    end
    if x6 < 10
        s = s * char(int('0') + x6)
    else
        s = s * char(int('A') + (x6 - 10))
    end
    if x7 < 10
        s = s * char(int('0') + x7)
    else
        s = s * char(int('A') + (x7 - 10))
    end
    if x8 < 10
        s = s * char(int('0') + x8)
    else
        s = s * char(int('A') + (x8 - 10))
    end
    return s
end

 

# 실행 시작 지점

if length(ARGS) < 1
    printUsage()
    exit(1)
end

fname = ARGS[1]

f = open(fname)
data = read(f, Int8)   

seek_end(f)   
fsize = position(f)   
seek(f, 0)   

@printf("The size of the file \"%s\" is %d.\n\n", fname, fsize)

n = 0
t = ""

for i = 1: fsize
    if n % 16 == 0
        @printf("%s: ", toHex8(n))
    end
    c = read(f, Int8)   
    @printf(" %s", toHex(c))
    if c < int8(' ') || c > 0x7F
        t *= "."
    else
        t *= char(c)
    end
    n += 1
    if n % 16 == 0
        @printf("  |%s|\n", t)
        t = ""
    end
end

if t != ""
    for i = 1: (16 - (n % 16))
        @printf("   ")
    end
    @printf("  |%s", t)
    for i = 1: (16 - (n % 16))
        @printf(" ")
    end
    @printf("|\n")
end

close(f)

@printf("\nRead %d bytes.\n", n)

 

 

 실행하기 예 1> julia testHexView_02.jl temp_1.bin
The size of the file "temp_1.bin" is 12.

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

Read 12 bytes.

 

 실행하기 예 2> julia testHexView_02.jl myFile.ser
The size of the file "myFile.ser" is 130.

0000 0000:  AC ED 00 05 73 72 00 06 50 65 72 73 6F 6E 07 31  |....sr..Person.1|
0000 0010:  46 DB A5 1D 44 AB 02 00 03 49 00 03 61 67 65 4C  |F...D....I..ageL|
0000 0020:  00 09 66 69 72 73 74 4E 61 6D 65 74 00 12 4C 6A  |..firstNamet..Lj|
0000 0030:  61 76 61 2F 6C 61 6E 67 2F 53 74 72 69 6E 67 3B  |ava/lang/String;|
0000 0040:  4C 00 08 6C 61 73 74 4E 61 6D 65 71 00 7E 00 01  |L..lastNameq.~..|
0000 0050:  78 70 00 00 00 13 74 00 05 4A 61 6D 65 73 74 00  |xp....t..Jamest.|
0000 0060:  04 52 79 61 6E 73 71 00 7E 00 00 00 00 00 1E 74  |.Ryansq.~......t|
0000 0070:  00 07 4F 62 69 2D 77 61 6E 74 00 06 4B 65 6E 6F  |..Obi-want..Keno|
0000 0080:  62 69                                            |bi              |

Read 130 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 )

 

Julia 언어에는 지수 연산자 ^ 를 (밑수)^(지수) 의 형식으로 언어 자체에서 지원하고 있다. 하지만 차후 필요한 데가 있을 것 같아서 이와 유사한 n 제곱 함수와 n 제곱근 함수를 구현해 보았다. (참고로 Julia 언어에는 pow() 함수가 정의되어 있지 않다.)

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

 

#!/usr/bin/env julia

# Filename: testNthRoot.jl
#
#            Approximate square roots, cubic roots and n-th roots of a given number.
#
# Execute: julia testNthRoot.jl
#
# Compile: ipy %IRONPYTHON_HOME%\tools\scripts\pyc.py /main:testNthRoot.py /target:exe
# Execute: testNthRoot
#
# Date: 2013. 3. 7.
# Copyright (c) 2013 PH Kim  (pkim __AT__ scripts.pe.kr)


MAX_ITER = 20000
M_EPSILON = 1.0e-15

#
# Compute the n-th root of x to a given scale, x > 0.
#
function nPow(a, n)
    if n > 0
        if n == 1
            return a
        else
            if a == 0.0 || a == 1.0
                return a
            elseif a == -1.0
                if n % 2 == 1
                    return -1.0
                else
                    return 1.0
                end
            elseif a < 0.0
                if n % 2 == 1
                    return -nPow(-a, n)
                else
                    return nPow(-a, n)
                end
            else
                y = 1.0
                for i = 1:n
                    y *= a
                end
                return y
            end
        end
    elseif n == 0
        return 1.0
    else      #  when n < 0
        if a == 0.0
            println("Error")   # throws "Negative powering exception of zero."
        else
            if n == -1
                return 1.0/a
            else
                return 1.0/nPow(a, -n)
            end
        end
    end
end

#
# Compute the n-th root of x to a given scale, x > 0.
#
function gPow(a, n)
    if n > 0
        if n == 1
            return a
        else
            if a == 0.0 || a == 1.0
                return a
            elseif a == -1.0
                if n % 2 == 1
                    return -1.0
                else
                    return 1.0
                end
            elseif a < 0.0
                if n % 2 == 1
                    return -gPow(-a, n)
                else
                    return gPow(-a, n)
                end
            else
                y = 1.0
                r = a
                m = 8*4 - 1            #  8*sizeof(int) - 1;
                one = 1
                for i = 0:m
                    if (n & one) == 0
                        y *= 1.0
                    else
                        y *= r
                    end
                    r = r*r
                    one <<= 1
                    if one > n
                        break
                    end
                end
                return y
            end
        end
    elseif n == 0
        return 1.0
    else      #  when n < 0
        if a == 0.0
            throw("Negative powering exception of zero.")
        else
            if n == -1
                return 1.0/a
            else
                return 1.0/gPow(a, -n)
            end
        end
    end
end

#
# Compute the n-th root of x to a given scale, x > 0.
#
function mPow(a, n)
    if n > 0
        if n == 1
            return a
        else
            if a == 0.0 || a == 1.0
                return a
            elseif a == -1.0
                if n % 2 == 1
                    return -1.0
                else
                    return 1.0
                end
            elseif a < 0.0
                if n % 2 == 1
                    return -mPow(-a, n)
                else
                    return mPow(-a, n)
                end
            else
                y = 1.0
                r = a
                m = n
                while m > 0
                    if (m & 0x1) == 1
                        y *= r
                    end
                    r = r*r
                    m >>= 1
                end
                return y
            end
        end
    elseif n == 0
        return 1.0
    else      #  when n < 0
        if a == 0.0
            throw("Negative powering exception of zero.")
        else
            if n == -1
                return 1.0/a
            else
                return 1.0/mPow(a, -n)
            end
        end
    end
end

#
# Compute the square root of x to a given scale, x > 0.
#
function heronSqrt(a)
    if a < 0.0
        throw("Cannot find the sqrt of a negative number.")
    elseif a == 0.0 || a == 1.0
        return a
    else
        x1 = a
        x2 = (x1 + a/x1)/2.0
        er = x1 - x2
        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
            end
            counter += 1
            if counter > MAX_ITER
                break
            end
        end
        if counter >= MAX_ITER
            throw("Inaccurate sqrt exception by too many iterations.")
        end
        return x2
    end
end


#
# Compute the cubic root of x to a given scale, x > 0.
#
function newtonCbrt(a)
    if a == 0.0 || a == 1.0 || a == -1.0
        return a
    elseif a < 0.0
        return -newtonCbrt(-a)
    else
        x1 = a
        x2 = (2.0*x1 + a/(x1*x1))/3.0
        # println("    x2 = $x2")
        er = x1 - x2
        counter = 0
        while x1 + er != x1
            x1 = x2
            x2 = (2.0*x1 + a/(x1*x1))/3.0
            # println("        x2 = $x2")
            er = x1 - x2
            # println("        abs(er) = $(abs(er))")
            # println("        abs(M_EPSILON*x1) = $(abs(M_EPSILON*x1))")
            if abs(er) < abs(M_EPSILON*x1)
                break
            end
            counter += 1
            if counter > MAX_ITER
                break
            end
        end
        if counter >= MAX_ITER
            throw("Inaccurate cbrt exception by too many iterations.")
        end
        return x2
    end
end


#
# Compute the n-th root of x to a given scale, x > 0.
#
function newtonNthRoot(n, a)
    if n == 0
        return 1.0
    elseif n == 1
        return a
    elseif n > 0
        if a == 0.0 || a == 1.0
            return a
        elseif a == -1.0
            if n % 2 == 1
                return a
            else
                throw("Cannot find the even n-th root of a negative number.")
            end
        elseif a < 0.0
            if n % 2 == 1
                return -newtonNthRoot(n, -a)
            else
                throw("Cannot find the even n-th root of a negative number.")
            end
        elseif a < 1.0
            return 1.0/newtonNthRoot(n, 1.0/a)
        else
            x1 = a
            xn = mPow(x1, n - 1)
            x2 = ((n - 1)*x1 + a/xn)/n
            er = x1 - x2
            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
                end
                counter += 1
                if counter > MAX_ITER
                    break
                end
            end
            if counter >= MAX_ITER
                throw("Inaccurate n-th root exception by too many iterations.")
            end
            return x2
        end
    else
        if a == 0.0
            throw("Cannot find the negative n-th root of zero.")
        else
            return 1.0/newtonNthRoot(-n, a)
        end
    end
end


x = 16.0
u = sqrt(x)

println("[ Testing heronSqrt(double) ]--------------------")
@printf("x = %f\n", x)
@printf("u = sqrt(%f) = %f\n", x, u)
y = heronSqrt(x)
@printf("y = heronSqrt(%f) = %f\n", x, y)
@printf("y*y = %f\n", y*y)
println()

println("[ Testing newtonCbrt(double) ]--------------------")
x = -216.0
@printf("x = %f\n", x)
@printf("-exp(log(-x)/3.0) = %f\n", -exp(log(-x)/3.0))
w = newtonCbrt(x)
@printf("w = newtonCbrt(%f) = %f\n", x, w)
@printf("w*w*w = %f\n", w*w*w)
println()

x = 729000000000.0
@printf("x = %f\n", x)
@printf("exp(log(x)/3.0) = %f\n", exp(log(x)/3.0))
w = newtonCbrt(x)
@printf("w = newtonCbrt(%f) = %f\n", x, w)
@printf("w*w*w = %f\n", w*w*w)
println()

println("[ Testing newtonNthRoot(int, double) ]--------------------")
z = newtonNthRoot(3, x)
@printf("x = %f\n", x)
@printf("z = newtonNthRoot(3, %f) = %f\n", x, z)
@printf("z*z*z = %f\n", z*z*z)
println()

x = 12960000000000000000.0
z = newtonNthRoot(4, x)
println("x = $x")
println("z = newtonNthRoot(4, x) = newtonNthRoot(4, $x) = $z")
@printf("z*z*z*z = %f\n", z*z*z*z)
println()

x = 1.0/12960000000000000000.0
z = newtonNthRoot(4, x)
println("x = $x")
@printf("exp(log(x)/4.0) = %f\n", exp(log(x)/4.0) )
println("z = newtonNthRoot(4, x) = newtonNthRoot(4, $x) = $z")
println("z*z*z*z = $(z*z*z*z)" )
println()


try
        x = -4.0
        println("[ Test Exception heronSqrt(double) ]--------------------")
        println("x = $x")
        println("Calculating heronSqrt($x)")
        y = heronSqrt(x)
        println("y = heronSqrt($x) = $y")
        println("y*y = $(y*y)")
        println()
catch ex
        println("$ex\nCaught some exception in calculating heronSqrt($x)")
        println()
end


try
        x = -4.0
        println("[ Test Exception in newtonCbrt(double) ]--------------------")
        println("x = $x")
        println("Calculating newtonCbrt($x)")
        y = newtonCbrt(x)
        println("y = newtonCbrt($x) = $y")
        println("y*y*y = $(y*y*y)")
        println()
catch ex
        println("$ex\nCaught some exception in calculating newtonCbrt$x)")
        println()
end


println("[ Test calculations by powering ]-----------------------------")
x = 200.0
z = newtonNthRoot(10, x)
println("x = $x")
println("exp(log(x)/10.0) = $(exp(log(x)/10.0))")
println("z = newtonNthRoot(10, x) = newtonNthRoot(10, $x) = $z")
println("z^10 = $(z^10)")
println()


x = 3001.0
z = newtonNthRoot(99, x)
println("x = $x")
println("exp(log(x)/99.0) = $(exp(log(x)/99.0))")
println("z = newtonNthRoot(99, x) = newtonNthRoot(99, $x) = $z")
println("z^99 = $(z^99)")
println()


x = 3001.0
z = newtonNthRoot(-99, x)
println("x = $x")
println("exp(log(x)/-99.0) = $(exp(log(x)/-99.0))")
println("z = newtonNthRoot(-99, x) = newtonNthRoot(-99, $x) = $z")
println("1.0/z^99 = $(1.0/(z^99))")
println("z^(-99) = $(z^(-99))")
println()


println("2.1^2.1 = $(2.1^ 2.1)")
println("2.1^2.1 * 2.1^(-2.1) = $(2.1^2.1 * 2.1^(-2.1))")
println("2.1^2.1 = exp(2.1*log(2.1)) = $(exp(2.1*log(2.1)))")
println("2.1^(-2.1) = exp(-2.1*log(2.1)) = $(exp(-2.1*log(2.1)))")
println("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))) = $( exp(2.1*log(2.1)) * exp(-2.1*log(2.1)) )")
println()


k = 301
x = -1.029
t1 = nPow(x, k)
t2 = gPow(x, k)
t3 = mPow(x, k)
println("$x^$k = $(x^k)")
println("t1 = nPow($x, $k) = $t1")
println("t2 = gPow($x, $k) = $t2")
println("t3 = mPow($x, $k) = $t3")
println("t1 / t2 = $(t1 / t2)")
println("t1 - t2 = $(t1 - t2)")
print("t1 == t2 ? ")
if t1 == t2
    print("yes")
else
    print("no")
end
println()
println("t1 / t3 = $(t1 / t3)")
println("t1 - t3 = $(t1 - t3)")
print("t1 == t3 ? ")
if t1 == t3
    print("yes")
else
    print("no")
end
println()
println("t2 / t3 = $(t2 / t3)")
println("t2 - t3 = $(t2 - t3)")
print("t2 == t3 ? ")
if t2 == t3
    print("yes")
else
    print("no")
end
println()
println()
println("Done.")


"""
[ Testing heronSqrt(double) ]--------------------
x = 16.000000
u = sqrt(16.000000) = 4.000000
y = heronSqrt(16.000000) = 4.000000
y*y = 16.000000

[ Testing newtonCbrt(double) ]--------------------
x = -216.000000
-exp(log(-x)/3.0) = -6.000000
w = newtonCbrt(-216.000000) = -6.000000
w*w*w = -216.000000

x = 729000000000.000000
exp(log(x)/3.0) = 9000.000000
w = newtonCbrt(729000000000.000000) = 9000.000000
w*w*w = 729000000000.000000

[ Testing newtonNthRoot(int, double) ]--------------------
x = 729000000000.000000
z = newtonNthRoot(3, 729000000000.000000) = 9000.000000
z*z*z = 729000000000.000000

x = 1.296e19
z = newtonNthRoot(4, x) = newtonNthRoot(4, 1.296e19) = 60000.0
z*z*z*z = 12960000000000000000.000000

x = 7.716049382716049e-20
exp(log(x)/4.0) = 0.000017
z = newtonNthRoot(4, x) = newtonNthRoot(4, 7.716049382716049e-20) = 1.6666666666
666667e-5
z*z*z*z = 7.716049382716051e-20

[ Test Exception heronSqrt(double) ]--------------------
x = -4.0
Calculating heronSqrt(-4.0)
Cannot find the sqrt of a negative number.
Caught some exception in calculating heronSqrt(-4.0)

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

[ Test calculations by powering ]-----------------------------
x = 200.0
exp(log(x)/10.0) = 1.6986464646342472
z = newtonNthRoot(10, x) = newtonNthRoot(10, 200.0) = 1.6986464646342472
z^10 = 199.9999999999999

x = 3001.0
exp(log(x)/99.0) = 1.0842361893258805
z = newtonNthRoot(99, x) = newtonNthRoot(99, 3001.0) = 1.0842361893258805
z^99 = 3000.999999999995

x = 3001.0
exp(log(x)/-99.0) = 0.9223082662659932
z = newtonNthRoot(-99, x) = newtonNthRoot(-99, 3001.0) = 0.9223082662659932
1.0/z^99 = 3001.000000000005
z^(-99) = 3001.0000000000045

2.1^2.1 = 4.749638091742242
2.1^2.1 * 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.21054235726688478
2.1^2.1 * 2.1^(-2.1) = exp(2.1*log(2.1)) * exp(-2.1*log(2.1)) = 4.74963809174224
2 * 0.21054235726688478 = 1.0

-1.029^301 = -5457.928015771622
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-11
t1 == t2 ? no
t1 / t3 = 0.9999999999999887
t1 - t3 = 6.184563972055912e-11
t1 == t3 ? no
t2 / t3 = 1.0
t2 - t3 = 0.0
t2 == t3 ? yes

Done.
"""

 

 

Posted by Scripter
,

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

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

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

Julia 언어에서는 asin() 함수로 구현되어 있다.

 

# Filename: testArcSine.jl
#
# Execute: julia testArcSine.jl
#
# Date: 2013. 3. 7.
# Copyright (c) pkim _AT_ scripts.pe.kr

x = -0.9
y = asin(x)
@printf("y = asin(%.1f) = %.9f\n", x,  y)
@printf("sin(y) = sin(%.9f) = %.1f\n", y, sin(y))
println()

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

v = asinh(x)
@printf("v = asinh(%3.1f) = %.10f\n",x,  v)

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

 

"""
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 알고리즘은 Stirlng 공식에 의한 알고리즘 보다 정밀하며, 십진수로 유효숫자 약 15자리 까지는 정확하게 계산해 준다.  단지 exp 함수를 이용하는 부분에서는 exp 함수의 구현에 따라 오차가 더 있을 수 있다.

#!/usr/bin/env julia

# Filename: testLanczos-01.jl
#
#           An approximation for the gamma function by using the Lanczos algorithm
#
# Execute: julia testLanczos-01.jl
#         or
# Execute: ./testLanczos-01.jl
#
# See: http://en.wikipedia.org/wiki/Lanczos_approximation
# See:http://www-history.mcs.st-and.ac.uk/Biographies/Lanczos.html
# See: http://www.thinbasic.com/community/showthread.php?11279-Gamma-function

# Coefficients used by the GNU Scientific Library
g = 7
p = [0.99999999999980993, 676.5203681218851, -1259.1392167224028,
     771.32342877765313, -176.61502916214059, 12.507343278686905,
     -0.13857109526572012, 9.9843695780195716e-6, 1.5056327351493116e-7]
 
function gamma(z)
    z = complex(z)
    # Reflection formula
    # if z.real < 0.5
    if real(z) < 0.5
        return pi / (sin(pi*z)*gamma(1-z))
    else
        z -= 1
        x = p[1]
        for i =1:g+1
            x += p[i+1]/(z+i)
        end
        t = z + g + 0.5
        return sqrt(2*pi) * t^(z+0.5) * exp(-t) * x
    end
end

function factorial(n)
    if n < 2
        return 1
    else
        k = 1
        if n % 2 == 0
            for i = 0:div(n, 2)-1
                k *= (i + 1) * (n - i)
            end
        else
            for i = 0:div(n, 2)-1
                k *= (i + 1) * (n - 1 - i)
            end
            k *= n
        end
        return k
    end
end

function facto(n)
    if n < 2
        return BigInt(1)
    else
        k = BigInt(1)
        for i = 2:n
            k *= BigInt(i)
        end
        return k
    end
end


@printf("gamma(10) = 9! = %s asymptotically\n", real(gamma(10)))
@printf("gamma(101) = 100! = %s asymptotically\n", real(gamma(101)))
for i = 0:10
    @printf("%d! = %d\n", i, factorial(i))
end
  
i = 100
@printf("factorial(%d) = %d! = %s\n", i, i, factorial(BigInt(i)))
@printf("facto(%d) = %d! = %s\n", i, i, facto(BigInt(i)))


"""
Output:
gamma(10) = 9! = 362880.0000000015 asymptotically
gamma(101) = 100! = 9.332621544393794e157 asymptotically
0! = 1
1! = 1
2! = 2
3! = 6
4! = 24
5! = 120
6! = 720
7! = 5040
8! = 40320
9! = 362880
10! = 3628800
factorial(100) = 100! = 93326215443944152681699238856266700490715968264381621468
59296389521759999322991560894146397615651828625369792082722375825118521091686400
0000000000000000000000
facto(100) = 100! = 933262154439441526816992388562667004907159682643816214685929
63895217599993229915608941463976156518286253697920827223758251185210916864000000
000000000000000000
"""

 

 



Posted by Scripter
,

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

         p(x) = (ax - b)q(x) + r

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

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


아래의 소스파일은 파일 testSyntheticDivision.jl 을 수정한 것이다.

python 대신 jython이나 IronPython 으로도 수정 없이 그대로 실행된다.


  1. ##  Filename: testSyntheticDivision2.jl
  2. ##
  3. ##  Purpose:  Find the quotient and remainder when some polynomial is
  4. ##            divided by a monic polynomial of the first degree.
  5. ##
  6. ##  Execute:  julia testSyntheticDivision2.jl 5 -4 7 8 6 8
  7. ##
  8. ##      Date:  2013. 3. 7.
  9. # 사용법 표시
  10. function printUsage()
  11.     println("사용법: python testSyntheticDivision2.py [제식의 계수] [피제식의 계수들]")
  12.     println("조립제법(synthetic method)에 의한 다항식 나눗셈 결과를 보여준다.")
  13. end
  14. # 부동소수점수의 표현이 .0 으로 끝나는 경우 이를 잘라낸다.
  15. # 전체 문자열 표시 너비는 매개변수 width 로 전달받아 처리한다.
  16. function simplify(v, width)
  17.     t = string("", round(v,13))
  18.     tlen = length(t)
  19.     if tlen >1 && t[tlen-1:tlen] == ".0"
  20.         t = t[1:tlen-2]
  21.     end
  22.     tlen = length(t)
  23.     if width > 0
  24.         if tlen < width
  25.             t = string("                "[1: width - tlen], t)
  26.         end
  27.     end
  28.     return t
  29. end
  30. # "/수" 표시하기
  31. # 부동소수점수의 표현이 .0 으로 끝나는 경우 이를 잘라낸다.
  32. # 전체 문자열 표시 너비는 매개변수 width 로 전달받아 처리한다.
  33. function simplifyReciprocal(v, width)
  34.     t = string("", round(v,13))
  35.     tlen = length(t)
  36.     if tlen > 2 && t[tlen-1:tlen] == ".0"
  37.         t = t[1:tlen-2]
  38.     end
  39.     if width > 0
  40.         if tlen < width
  41.             t = string("                "[1: width - tlen], t)
  42.         end
  43.     end
  44.     return t
  45. end
  46. # 다항식을 내림차순의 스트링 표현으로 반환
  47. function toPolyString(c)
  48.     t = ""
  49.     sc0 = simplify(c[1], 0)
  50.     if length(c) > 2
  51.         if sc0 == "1"
  52.             t = string(t,  "x^$(length(c)-1)")
  53.         elseif sc0 == "-1"
  54.             t = string(t,  "-x^$(length(c)-1)")
  55.         else
  56.             t = string(t, sc0 , " x^$(length(c)-1)")
  57.         end
  58.     elseif length(c) == 2
  59.         if sc0 == "1"
  60.             t = string(t, "x")
  61.         elseif sc0 == "-1"
  62.             t = string(t, "-x")
  63.         else
  64.             t = string(t, sc0, " x")
  65.         end
  66.     elseif length(c) == 1
  67.         t = string(t, sc0)
  68.     end
  69.     for i = 2: length(c)
  70.         k = length(c)  - i
  71.         sc = simplify(c[i], 0)
  72.         if k > 1
  73.             if c[i] > 0.0
  74.                 if sc == "1"
  75.                     t = string(t, " + ", "x^$(k)")
  76.                 else
  77.                     t = string(t, " + ", sc, " x^$(k)")
  78.                 end
  79.             elseif c[i] < 0.0
  80.                 if sc == "-1"
  81.                     t = string(t, " - ", "x^$(k)")
  82.                 else
  83.                     t = string(t, " - ", simplify(abs(c[i]), 0), " x^$(k)")
  84.                 end
  85.             end
  86.         elseif k == 1
  87.             if c[i] > 0.0
  88.                 if sc == "1"
  89.                     t = string(t, " + ", "x")
  90.                 else
  91.                     t = string(t, " + ", sc, " x")
  92.                 end
  93.             elseif c[i] < 0.0
  94.                 if sc == "-1"
  95.                     t = string(t, " - ", "x")
  96.                 else
  97.                     t = string(t, " - ", simplify(abs(c[i]), 0), " x")
  98.                 end
  99.             end
  100.         elseif k == 0
  101.             if c[i] > 0.0
  102.                 t = string(t, " + ", sc)
  103.             elseif c[i] < 0.0
  104.                 t = string(t, " - ", simplify(abs(c[i]), 0))
  105.             end
  106.         end
  107.     end
  108.     return t
  109. end
  110. # 다항식 나눗셈 결과를
  111. #     (피제식) = (제식)(몫) + (나머지)
  112. # 형태로 출력
  113. function printDivisionResult(a, c, d, b)
  114.     strLine = "  " * toPolyString(c)
  115.     println( strLine )
  116.     strLine = "    = ( " * toPolyString( [a[1], -a[2]] ) * " )"
  117.     tmp = [0.0 for i = 1:(length(b) - 1) ]
  118.     for i = 1:length(tmp)
  119.         tmp[i] = b[i]
  120.     end
  121.     strLine = string(strLine, "( ", toPolyString(tmp), " )")
  122.     r = d[length(d)]
  123.     if r > 0.0
  124.         strLine = string(strLine, " + ", simplify(r, 0))
  125.     elseif r < 0.0
  126.         strLine = string(strLine, " - ", simplify(abs(r), 0))
  127.     end
  128.     println( strLine )
  129. end
  130. # 조립제법 계산표 출력 함수
  131. function printSyntheticTable(a, c, s, d, q)
  132.     strLine = "         | "
  133.     strLine = string(strLine, simplify(c[1], 8))
  134.     for i = 2:length(c)
  135.         strLine = string(strLine, "  ", simplify(c[i], 8))
  136.     end
  137.     println( strLine )
  138.     strLine = string(simplify(a[2], 8), " |")
  139.     strLine = string(strLine, "           ")
  140.     strLine = string(strLine, simplify(s[2], 8))
  141.     for i = 3:length(s)
  142.         strLine = string(strLine, "  ", simplify(s[i], 8))
  143.     end
  144.     println( strLine )
  145.     strLine = "         |"
  146.     for i = 1:length(q)
  147.         strLine = string(strLine, "----------")
  148.     end
  149.     println( strLine )
  150.     strLine = "         | "
  151.     strLine = string(strLine, simplify(d[1], 8))
  152.     for i = 2:length(d)
  153.         strLine = string(strLine, "  ", simplify(d[i], 8))
  154.     end
  155.     println( strLine )
  156.     strLine = simplifyReciprocal(a[1], 10) * " | "
  157.     strLine = string(strLine, simplify(q[1], 8))
  158.     for i = 2:length(q) - 1
  159.         strLine = string(strLine, "  ", simplify(q[i], 8))
  160.     end
  161.     println( strLine )
  162. end
  163. # 실행 시작 지점
  164. if length(ARGS) < 4
  165.     printUsage()
  166.     exit(1)
  167. end
  168. ######################################################
  169. # 피제식은 c_0 x^n +  c_1 x^(n -1) + ... + c_n
  170. # 제식은 a x -  b
  171. a = [ float64(parse_float(ARGS[1]) ), - float64(parse_float(ARGS[2]) ) ]
  172. c = [0.0 for i=1:length(ARGS) - 2 ]
  173. s = [0.0 for i=1:length(ARGS) - 2 ]
  174. d = [0.0 for i=1:length(ARGS) - 2 ]
  175. b = [0.0 for i=1:length(ARGS) - 2 ]
  176. for i = 1:length(c)
  177.     c[i] = float64(parse_float(ARGS[i + 2]))
  178. end
  179. ######################################################
  180. # 조립제법의 주요 부분
  181. s[1] = 0.0
  182. d[1] = c[1]
  183. b[1] = c[1] / a[1]
  184. for i in 2:length(c)
  185.     s[i] = b[i-1]*a[2]
  186.     d[i] = c[i] + s[i]
  187.     b[i] = d[i] / a[1]
  188. end
  189. ######################################################
  190. # 몫의 계수와 나머지를 출력한다.
  191. print("몫의 계수는 ")
  192. for i = 1:length(b)-2
  193.     print(simplify(b[i], 0), ", " )
  194. end
  195. print(simplify(b[length(b) - 1], 0), " ")
  196. println("이고, 나머지는 ", simplify(d[length(d)], 0), " 이다.")
  197. println("")
  198. ######################################################
  199. # 조립제법 표를 출력한다.
  200. printSyntheticTable(a, c, s, d, b)
  201. println()
  202. ######################################################
  203. # (피제식) = (제식) x (몫) + (나머지)
  204. printDivisionResult(a, c, d, b)



실행> julia testSyntheticDivision2.jl 5 -4 7 8 6 8
몫의 계수는 1.4,  2.72,  3.376 이고, 나머지는 21.504 이다.

         |        7         8         6         8
       4 |                5.6     10.88    13.504
         |----------------------------------------
         |        7      13.6     16.88    21.504
      /5 |      1.4      2.72     3.376

  7 x^3 + 8 x^2 + 6 x + 8
    = ( 5 x - 4 )( 1.4 x^2 + 2.72 x + 3.376 ) + 21.504



Posted by Scripter
,

Julia 언어로 숫자 맞추기 게임을 작성해 보았다.

             sbuf = readline(STDIN) 

은 컨솔에서 한 줄을 스트링으로 입력받는 부분이고,

             guess = parse_int(sbuf)

은 입력받은 스트링을 정수로 타입변환하는 부분이다.



소스 파일명: guessNumber01.jl

  1. ##   Filename: guessNumber01.jl
  2. ##
  3. ##   Purpose:  Interatice game guessing a given number.
  4. ##                 if CONDITION
  5. ##                     ......
  6. ##                 elseif CONDITION
  7. ##                     ......
  8. ##                 else
  9. ##                     ......
  10. ##                 end
  11. ##
  12. ##   Execute: julia guessNumber01.jl
  13. function doGuessing(num)
  14.     println("Enter your guess:")
  15.     sbuf = readline(STDIN)
  16.     guess = parse_int(sbuf)
  17.     if guess == num
  18.         println("You win!")
  19.         return
  20.     end
  21.     # we won't get here if guess == num
  22.     if guess < num
  23.         println("Too low!")
  24.         doGuessing(num)
  25.     else
  26.         println("Too high!")
  27.         doGuessing(num)
  28.     end
  29. end
  30. doGuessing(123)



실행> julia guessNumber01.jl
Enter your guess:
111
Too low!
Enter your guess:
222
Too high!
Enter your guess:
123
You win!



위의 소스는 Jython 2.2.1이나 Jython 2.5.1로 실행해도 똑같이 실행된다.

실행> jython guessNumber01.py
Enter your guess:
111
Too low!
Enter your guess:
222
Too high!
Enter your guess:
123
You win!




Posted by Scripter
,


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

Python 언어에서는 // 가 정수 나눗셈 연산자이지만, Julia  언어에서는 // 가 분수를 표현할 때 쓰는 분자와 분모의 구분자이다. Julia 언어에서는 div(피제수, 제수) 가 정수 나눗셈에 쓰이는 함수이다. 즉

        y = int64(floor(x / 10))
        y = div(x, 10)

는 둘 다 정수 x 를 정수 10 으로 나눈 몫을 변수 y 에 저장하는 Julia 구문이다.

 

## Filename: makeMultTable.jl
##
##     Print a multiplication table.
##
##     Execute: julia makeMultTable.jl 230 5100
##
##      Date:  2013. 3. 5.
##    Author:  pkim __AT__ scripts ((DOT)) pe ((DOT)) kr


function printUsing()
    println("Using: julia makeMultTable.jl [number1] [number2]")
    println("Print a multiplication table for the given two integers.")
end

function printMultTable(x, y)
    nx = x
    if nx < 0
        nx = -nx
    end
    ny = y
    if ny < 0
        ny = -ny
    end
    ntail1 = 0
    ntail2 = 0
    while nx % 10 == 0
        # nx = int64(floor(nx / 10))
        nx = div(nx, 10)
        ntail1 = ntail1 + 1
    end
    while ny % 10 == 0
        # ny = int64(floor(ny / 10))
        ny = div(ny, 10)
        ntail2 = ntail2 + 1
    end
    z = nx * ny
    strZ = "$z"
    strX = "$nx"
    strY = "$ny"
    n = length(strY)
    zeros  = "0000000000000000000000000000000000000000"
    whites = "                                        "
    bars   = "----------------------------------------"
    loffset = "       "
    line4 = loffset * strZ
    line1 = loffset * whites[1: length(strZ) - length(strX)] * strX
    line2 = "   x ) " *  whites[1: length(strZ) - length(strY)] * strY
    line3 = "     --" *  bars[1: length(strZ)]
    println(line1 * zeros[1: ntail1])
    println(line2 * zeros[1: ntail2])
    println(line3)
    # println("strY = $strY")
    if length(strY) > 1
        for i = 0:length(strY)-1
            y1 = int64(strY[length(strY) - i : length(strY) - i])
            if y1 != 0
                strT = string(nx * y1)
                println(loffset * whites[1: length(strZ) - length(strT) - i] * strT)
            end
        end
        println(line3)
    end
    println(line4 * zeros[1: ntail1] * zeros[1: ntail2])
end


if length(ARGS) >= 2
    x = int64(ARGS[1])
    y = int64(ARGS[2])
    println()
    printMultTable(x, y)
else
    printUsing()
end



실행> julia makeMultTable.jl 230 5100
결과>

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

 

Posted by Scripter
,
▒ Julia 소스:  testStringReverse.jl

a = "Hello, world!"
println("a = ", a)
println("length(a) = ", length(a))
println("reverse(a) = ", reverse(a))
println()

b = "안녕하세요?"
println("b = ", b)
println("length(b) = ", length(b))
println("reverse(b) = ", reverse(b))

##############################
# Output:
# a = Hello, world!
# length(a) = 13
# reverse(a) = !dlrow ,olleH
#
# b = 안녕하세요?
# length(b) = 6
# reverse(b) = ?요세하녕안
##############################

 

위의 예제에서 보듯이 Julia 는 유니코드 문자열을 잘 지원한다.
그 대신 소스 파일을 UTF-8 인코딩으로 저장해야 한다.

Julia 대화형 모드에서는 readline 관계로 한글이 입력되지 않는다.


 

Posted by Scripter
,

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


  1. ##  Filename: makeDivisionTable.jl
  2. ##
  3. ##  Purpose:  Make a division table in a handy written form.
  4. ##
  5. ##  Execute: julia makeDivisionTable.jl 12345 32
  6. ##           julia makeDivisionTable.jl 500210 61
  7. ##
  8. ##      Date:  2013. 3. 5.
  9. ##    Author:  pkim __AT__ scripts ((DOT)) pe ((DOT)) kr
  10. function printUsage()
  11.     # println("Using: julia makeDivisionTable.jl [numerator] [denominator]")
  12.     # println("Make a division table in a handy written form.")
  13.     println("사용법: julia makeDivisionTable.jl [피제수] [제수]")
  14.     println("손으로 작성한 형태의 나눗셈 표를 만들어준다.")
  15. end
  16. function simplify(v, width)
  17.     t = string(v)
  18.     slen = length(t)
  19.     if slen >=2 && t[slen-1:slen] == ".0"
  20.         t = t[0:slen - 2]
  21.     end
  22.     slen = length(t)
  23.     if slen < width
  24.         t = " " ^(width - slen) * t
  25.     end
  26.     return t
  27. end
  28. function getSuffix(v)
  29.     t = v % 10
  30.     suffix = "은"
  31.     if length(search("2459", "$t")) >= 1
  32.         suffix = "는"
  33.     end
  34.     return suffix
  35. end
  36. function makeTable(numer, denom, quotient)
  37.     strNumer = "$numer"
  38.     strDenom = "$denom" 
  39.     strQuotient = "$quotient"
  40.     lenN = length(strNumer)
  41.     lenD = length(strDenom)
  42.     lenQ = length(strQuotient)
  43.     offsetLeft = 3 + lenD + 3
  44.     spaces = "                                                                                 "
  45.     uline  = "_" ^ (lenN + 2)
  46.     sline  = "-" ^ lenN
  47.     bias = lenN - lenQ
  48.     println(spaces[1:offsetLeft] * spaces[1:bias] * "$quotient")
  49.     println(spaces[1:offsetLeft - 2] * uline)
  50.     print("   " * strDenom * " ) " * strNumer)
  51.     strTmpR = strNumer[1: bias + 1]
  52.     tmpR = int64(strTmpR)
  53.     tmpSub = int64(0) :: Int64
  54.     oneDigit = ""
  55.     for i = 1:lenQ
  56.         if strQuotient[i: i] == "0"
  57.             if i + 1 <= lenQ
  58.                 oneDigit = strNumer[bias + i + 1: bias + i + 1]
  59.                 print(oneDigit)
  60.                 strTmpR = strTmpR * oneDigit
  61.                 tmpR = int64(strTmpR)
  62.             end
  63.         else
  64.             println("")
  65.             tmpSub = int64(strQuotient[i: i]) * denom
  66.             println(spaces[1: offsetLeft] * simplify(tmpSub, bias + i))
  67.             println(spaces[1: offsetLeft] * sline)
  68.             tmpR = tmpR - tmpSub
  69.             if tmpR == 0 && i + 1 <= lenQ
  70.                 print(spaces[1: offsetLeft] * spaces[1: bias + i])
  71.             else
  72.                 print(spaces[1: offsetLeft] * simplify(tmpR, bias + i))
  73.             end
  74.             strTmpR = "$tmpR"
  75.             if i + 1 <= lenQ
  76.                 oneDigit = strNumer[bias + i + 1: bias + i + 1]
  77.                 if oneDigit != ""
  78.                     print(oneDigit)
  79.                     strTmpR = strTmpR * oneDigit
  80.                 end
  81.                 tmpR = int64(strTmpR)
  82.             end
  83.         end
  84.     end
  85.     println("")
  86.     return tmpR
  87. end
  88. if length(ARGS) < 2
  89.     printUsage()
  90.     exit(1)
  91. end
  92. a = 0
  93. b = 0
  94. try
  95.     a = int64(ARGS[1])
  96.     b = int64(ARGS[2])
  97. catch ex
  98.     println(ex)
  99.     @printf("피제수: %s, 제수: %s\n", ARGS[1], ARGS[2])
  100.     println("숫자 입력에 오류가 있습니다.")
  101.     exit(1)
  102. end
  103. if a <= 0
  104.     @printf("피제수: %d\n", a)
  105.     println("피제수는 양의 정수라야 합니다.")
  106.     exit(1)
  107. elseif b <= 0
  108.     @printf("제수: %d\n", b)
  109.     println("제수는 양의 정수라야 합니다.")
  110.     exit(1)
  111. end
  112. q = int64(floor(a / b))
  113. r = a % b
  114. @printf("나눗셈 %s ÷ %s 의 결과: ", a, b)
  115. @printf("몫: %d, ", q)
  116. @printf("나머지: %ld\n", r)
  117. println("")
  118. k = makeTable(a, b, q)
  119. if k == r
  120.     @printf("\n나머지: %d\n", k)
  121. end
  122. if k == 0
  123.     @printf("%d = %d x %d", a, b, q)
  124.     @printf("%d%s %d의 배수(mupltiple)이다.\n", a, getSuffix(a), b)
  125.     @printf("%d%s %d의 약수(divisor)이다.\n", b, getSuffix(b), a)
  126. else
  127.     @printf("%d = %d x %d + %d\n", a, b, q, r)
  128.     @printf("%d%s %d의 배수(mupltiple)가 아니다.\n", a, getSuffix(a), b)
  129. end
  130. # -*- encoding: ms949 -*-
  131. #  Filename: makeDivisionTable.py
  132. #
  133. #  Purpose:  Make a division table in a handy written form.
  134. #
  135. #  Execute: python makeDivisionTable.py 12345 32
  136. #           python makeDivisionTable.py 500210 61
  137. #
  138. #     Date:  2008/05/15
  139. #   Author:  PH Kim   [ pkim ((AT)) scripts.pe.kr ]
  140. import sys
  141. def printUsage():
  142.     # print("Using: python makeDivisionTable.py [numerator] [denominator]")
  143.     # print("Make a division table in a handy written form.")
  144.     print("사용법: python makeDivisionTable.py [피제수] [제수]")
  145.     print("손으로 작성한 형태의 나눗셈 표를 만들어준다.")
  146. def simplify(v, width):
  147.     t = "%ld" % v
  148.     if t[-2:] == ".0":
  149.         t = t[0:len(t) - 2]
  150.     slen = len(t)
  151.     if slen < width:
  152.         t = " " * (width - slen) + t
  153.     return t
  154. def getSuffix(v):
  155.     t = v % 10L
  156.     suffix = "은"
  157.     if "2459".find("%d" % t) >= 0:
  158.         suffix = "는"
  159.     return suffix
  160. def makeTable(numer, denom, quotient):
  161.     strNumer = "%ld" % numer
  162.     strDenom = "%ld" % denom
  163.     strQuotient = "%ld" % quotient
  164.     lenN = len(strNumer)
  165.     lenD = len(strDenom)
  166.     lenQ = len(strQuotient)
  167.     offsetLeft = 3 + lenD + 3
  168.     spaces = "                                                                                 "
  169.     uline  = "_" * (lenN + 2)
  170.     sline  = "-" * lenN
  171.     bias = lenN - lenQ
  172.     print(spaces[0:offsetLeft] + spaces[0:bias] + "%ld" % quotient)
  173.     print(spaces[0:offsetLeft - 2] + uline)
  174.     sys.stdout.write("   " + strDenom + " ) " + strNumer)
  175.     strTmpR = strNumer[0: bias + 1]
  176.     tmpR = long(strTmpR)
  177.     tmpSub = 0L
  178.     oneDigit = None
  179.     for i in range(0, lenQ):
  180.         if strQuotient[i: i + 1] == "0":
  181.             if i + 1 < lenQ:
  182.                 oneDigit = strNumer[bias + i + 1: bias + i + 2]
  183.                 sys.stdout.write(oneDigit)
  184.                 strTmpR = strTmpR + oneDigit
  185.                 tmpR = long(strTmpR)
  186.         else:
  187.             print
  188.             tmpSub = long(strQuotient[i: i + 1]) * denom
  189.             print(spaces[0: offsetLeft] + simplify(tmpSub, bias + i + 1))
  190.             print(spaces[0: offsetLeft] + sline)
  191.             tmpR = tmpR - tmpSub
  192.             if tmpR == 0L and i + 1 < lenQ:
  193.                 sys.stdout.write(spaces[0: offsetLeft] + spaces[0: bias + i + 1])
  194.             else:
  195.                 sys.stdout.write(spaces[0: offsetLeft] + simplify(tmpR, bias + i + 1))
  196.             strTmpR = "%ld" % tmpR
  197.             if i + 1 < lenQ:
  198.                 oneDigit = strNumer[bias + i + 1: bias + i + 2]
  199.                 if oneDigit != None:
  200.                     sys.stdout.write(oneDigit)
  201.                     strTmpR = strTmpR + oneDigit
  202.                 tmpR = long(strTmpR)
  203.     print
  204.     return tmpR
  205. if len(sys.argv) < 3:
  206.     printUsage()
  207.     exit(1)
  208. a = None
  209. b = None
  210. try:
  211.     a = long(sys.argv[1])
  212.     b = long(sys.argv[2])
  213. except ValueError:
  214.     print("피제수: %s, 제수: %s" % (sys.argv[1], sys.argv[2]))
  215.     print("숫자 입력에 오류가 있습니다.")
  216.     sys.exit(1)
  217. if a <= 0L:
  218.     print("피제수: %ld" % a)
  219.     print("피제수는 양의 정수라야 합니다.")
  220.     sys.exit(1)
  221. elif b <= 0L:
  222.     print("제수: %ld" % b)
  223.     print("제수는 양의 정수라야 합니다.");
  224.     sys.exit(1)
  225. q = a / b
  226. r = a % b
  227. sys.stdout.write("나눗셈 %ld ÷ %ld 의 결과: " % (a, b))
  228. sys.stdout.write("몫: %ld, " % q)
  229. print("나머지: %ld" % r)
  230. print
  231. k = makeTable(a, b, q)
  232. if k == r:
  233.     print("\n나머지: %ld" % k)
  234. if k == 0L:
  235.     print("%ld = %ld x %ld" % (a, b, q))
  236.     print("%ld%s %ld의 배수(mupltiple)이다." % (a, getSuffix(a), b))
  237.     print("%ld%s %ld의 약수(divisor)이다." % (b, getSuffix(b), a))
  238. else:
  239.     print("%ld = %ld x %ld + %ld" % (a, b, q, r))
  240.     print("%ld%s %ld의 배수(mupltiple)가 아니다." % (a, getSuffix(a), b))
  241. end


실행> julia makeDivisionTable.jl 500210 61

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

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

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




Posted by Scripter
,

콘솔에 삼각형

         *
       * *
      *   *
     *     *
    *       *
   *         *
  *           *
 *             *
*****************


을 출력하는 Julia 소스 코드를 작성해 보자. 이런 소스 코드의 작성은 학원이나 학교에서 프로그래밍 입문자에게 과제로 많이 주어지는 것 중의 하나이다. 코끼리를 보거나 만진 사람들이 저마다 그 생김새를 말할 때 제각기 다르게 표현할 수 있듯이 이런 소스 코드의 작성도 알고 보면 얼마든지 많은 방법이 있을 것이다. 여기서는 쉬운 코드 부터 작성해 보고 차츰차츰 소스를 바꾸어 가면서 Julia 프로그래밍의 기초부분을 터득해 보기로 한다.

모든 소스 코드에서는 삼각형 출력 부분 담당 함수 printTriange()를 별도로 구현하였다.

우선 첫번 째 예제는 Julia 언어의 컨솔 출력 함수 println 의 사용법만 알면 누구나 코딩할 수 있는 매우 단순한 소스 코드이다.


삼각형 출력 예제 1
##  Filename: printTriangle1.jl
##            Print a triangle on console.
##
##  Execute: julia printTriangle1.jl
##
##      Date:  2013. 3. 5.
##    Author:  pkim __AT__ scripts ((DOT)) pe ((DOT)) kr

function printTriange()
    println("        *        ")
    println("       * *       ")
    println("      *   *      ")
    println("     *     *     ")
    println("    *       *    ")
    println("   *         *   ")
    println("  *           *  ")
    println(" *             * ")
    println("*****************")
end

printTriange()




위의 소스 코드는 아무 알고리즘도 없는 너무 단순한 코드이다. 이런 코드를 작성했다간 출력 모양이나 크기를 변경해야 하는 상황을 맞이하면 워드프로세서로 문서 만드는 것 이상으로 많은 수작업을 하거나 아니면 포기하는 지경에 이를 수도 있다. 그래서 다음 처럼 좀 더 나은 소스 코드를 작성하였다. Julia 언어의 출력 함수 print 와 prinln 을 적절히 섞어 구현하였다.


삼각형 출력 예제 2
##  Filename: printTriangle2.jl
##            Print a triangle on console.
##
##  Execute: julia printTriangle2.jl
##
##      Date:  2013. 3. 5.
##    Author:  pkim __AT__ scripts ((DOT)) pe ((DOT)) kr

function printTriange()
    for i = 0:7
        for k = 1:8-i
            print(" ")
        end
        for k = 1:2*i+2
            if k == 1 || k == 2*i+1
                print("*")
            else
                print(" ")
            end
        end
        for k = 1:8-i
            write(" ")
        end
        println("")
    end

    for i = 1:17
        print("*")
    end
    println("")
end

printTriange()



위의 소스 코드는 Julia 언어의 컨솔 출력 함수 print 와 println 그리고 for 반복 구문을 적절히 사용하여 구현되었다. 숫자 몇 곳만 수정하면 출력되는 삼각형의 크기를 바꿀 수 있다. 한 줄에 출력될 문자를 구성하는 알고리즘은 위의 예제와 근본적으로 같지만 println 과 배열을 만들어 한 즐씩 출력하는 소스 코드를 다음 예제와 같이 작성해 보았다.
또 빈칸 17개의 문자로 구성된 리스트를 생성하기 위한 구문은

        whites = [" " for i =1:17]

이다. (이 구문은 Python 언어의 [" "]*17 에 해당한다.)



삼각형 출력 예제 3
##  Filename: printTriangle3.jl
##            Print a triangle on console.
##
##  Execute: julia printTriangle3.jl
##
##      Date:  2013. 3. 5.
##    Author:  pkim __AT__ scripts ((DOT)) pe ((DOT)) kr

function printTriange()
    line2 = [" " for i =1:17]
    for i = 0:7
        line2 = [" " for i =1:17]
        line2[8-i+1] =  "*"
        line2[8+i+1] =  "*"
        println(join(line2, ""))
    end

    line2 = ["*" for i =1:17]
    for i = 1:17
        line2[i] =  "*"
    end
    println(join(line2, ""))
end

printTriange()




별(*) 문자를 이용하여 삼각형을 출력하는 일은 빈칸 문자와 별 문자응 적당한 좌표(위치)에 촐력하는 일이다. 출력될 한 줄의 스트링을 완성한 후 하나의 println 구문으로 출력하는 기법으로 소스 코드를 작성해 보았다. 소스 코드 중에

        whites = " "^17
        stars = "*"^17

은 지정된 개수(여기서는 17) 만큼 string을 중복 연결하는 구문이다.  (string^number 구문은 구문은 Groovy, Ruby, Python 언어의 string*number 에 해당한다.) 이들은 Julia 언어에서

        whites = repeat(" ", 17)
        stars = repeat("* ", 17)

로 작성해도 같은 의미이다.



삼각형 출력 예제 4
##  Filename: printTriangle4.jl
##            Print a triangle on console.
##
##  Execute: julia printTriangle4.jl
##
##      Date:  2013. 3. 5.
##    Author:  pkim __AT__ scripts ((DOT)) pe ((DOT)) kr

function printTriange()
    whites = " "^17
    stars  = "*"^17
    line2 = "$(whites[1:8])*$(whites[1:8])"
    println(line2)
    for i = 1:7
        line2 = "$(whites[1:8-i])*$(whites[8-i:7+i-1])*$(whites[7+i:])"
        println(line2)
    end
    println(stars)
end

printTriange()




string은 immutable이라 그 내용을 변경할 수 없지만, Julia 언어의 배열은 그 요소(item)를 아무 때 나 변경할 수 있다. 한 줄에 출력될 각 문자를 리스트 타입의 변수 line2에 저장한 다음 println 문으로 출력 시

    join(line2, "")

로 그 리스트의 모든 요소item)가 모두 연결되어 출력되게 하였다.



삼각형 출력 예제 5
##  Filename: printTriangle5.jl
##            Print a triangle on console.
##
##  Execute: julia printTriangle5.jl
##
##      Date:  2013. 3. 5.
##    Author:  pkim __AT__ scripts ((DOT)) pe ((DOT)) kr

function printTriange()
    whites = " "^17
    stars  = "*"^17
    start = 8
    line2 = [" " for i = 1:17]
    line2[start + 1] = "*"
    println(join(line2, ""))
    for i = 1:7
        line2 = [" " for i = 1:17]
        line2[start - i + 1] = stars[start - i + 1:start - i + 1]
        line2[start + i+ 1] = stars[start + i + 1:start + i + 1]
        println(join(line2, ""))
    end
    println(stars)
end

printTriange()




출력되는 삼각형이 좌우 대칭이라는 사실에 착안하여, 다음 소스 코드에서는  각 줄을 처음 8자, 중앙 한 문자, 끝 8자(처음 8자의 역순)로 string을 만들어 출력하였다.



삼각형 출력 예제 6
##  Filename: printTriangle6.jl
##            Print a triangle on console.
##
##  Execute: julia printTriangle6.jl
##
##      Date:  2013. 3. 5.
##    Author:  pkim __AT__ scripts ((DOT)) pe ((DOT)) kr

function printTriange()
    whites = " "^8
    stars  = "*"^8
    start = 8
    line = whites * '*' * whites
    println(line)
    for i = 1:7
        n = length(whites)
        line = whites[1:n-i] * "*" * whites[n-i+1:n-1]
        println(line * " " * reverse(line))
    end
    line = stars * '*' * stars
    println(line)
end

printTriange()




다음 소스 코드는 한 줄에 출력될 문자열의 데이터를 17비트 이진법 수로 구성하고, 이 이진법수의 비트가 0인 곳에는 빈칸을, 1인 곳에는 별(*)을 출력하는 기법으로 작성되었다.



삼각형 출력 예제 7
##  Filename: printTriangle7.jl
##            Print a triangle on console.
##
##  Execute: julia printTriangle7.jl
##
##      Date:  2013. 3. 5.
##    Author:  pkim __AT__ scripts ((DOT)) pe ((DOT)) kr

BASE36 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"

function itoa(num, radix)
   isNegative = false
   if num < 0
      isNegative = true
      num = -num
   end

   arr = ""
   q, r = num, 0
   while q >= radix
      # q, r = divmod(q, radix)
      r = mod(q, radix)
      q = div(q, radix)
      arr *= BASE36[r+1]
   end

   arr *= BASE36[q + 1]
   if isNegative
      arr *= "-"
   end

   return reverse(arr)
end


function printTriange()
    start = int(0x100) :: Int32
    total = 0
    val = start
    data = ""
    for k = 0:7
        val = (start << k) | (start >> k)
        data = itoa(val, 2)
        s = ""
        for i = 1:17 - length(data)
            s *= " "
        end
        for i = 1:length(data)
            if data[i] == '0'
                s *= " "
            else
                s *= "*"
            end
        end
        println(s)
        total += val
    end

    val = (start << 8) | (start >> 8)
    ## val = (1 << 16) | (start >> 8)
    total += val
    data = itoa(total, 2)
    s = ""
    for i = 1:length(data)
        if data[i] == '0'
            s *= " "
        else
            s *= "*"
        end
    end
    println(s)
end

printTriange()




기본적인 원리는 위의 소스 코드와 같지만 이진법수의 한 비트 마다 한 문자씩 츨력하는 대신에 출력될 한 줄의 string을 완성하여 이를 println 구문으로 출력하는 기법으로 재작성한 것이 다음의 소스 코드이다. anotherString = replace(string, 정규식, 타겟) 을 이용하여 모든 0을 빈칸으로, 모든 1을 별(*) 문자로 바꾸었으며, 별(*) 문자만으로 이루어진 마지막 줄 출력을 위해 변수 total을 준비하였다. for 반복 구문의 블럭 내에서 구문

            total |= val

이 하는 일이 무엇인지 이해할 수 있으면 좋겠다.



삼각형 출력 예제 8
##  Filename: printTriangle8.jl
##            Print a triangle on console.
##
##  Execute: julia printTriangle8.jl
##
##      Date:  2013. 3. 5.
##    Author:  pkim __AT__ scripts ((DOT)) pe ((DOT)) kr

BASE36 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"

function itoa(num, radix)
   isNegative = false
   if num < 0
      isNegative = true
      num = -num
   end

   arr = ""
   q, r = num, 0
   while q >= radix
      # q, r = divmod(q, radix)
      r = mod(q, radix)
      q = div(q, radix)
      arr *= BASE36[r+1]
   end

   arr *= BASE36[q + 1]
   if isNegative
      arr *= "-"
   end

   return reverse(arr)
end


function printTriange()
    zeros  = "00000000"
    start = int(0x100) :: Int32
    total = 0
    val = start
    line = ""
    data = ""
    for k = 0:7
        val = (start << k) | (start >> k)
        data = itoa(val, 2)
        line = zeros[1:17-length(data)] * data
        line = replace(line, "0", " ")
        line = replace(line, "1", "*")
        println(line)
        total |= val
    end

    val = (start << 8) | (start >> 8)
    total |= val
    line = itoa(total, 2)
    line = replace(line, "0", " ")
    line = replace(line, "1", "*")
    println(line)
end

printTriange()




소스 코드가 처음 것 보다 매우 복잡해졌지만, Julia 안어의 배열을 이용해서 구현해 보았다. 별(*) 문자만으로 구성된 마지막 줄 출력을 위해 배열 타입의 변수 last를 준비하였다. 또 배열에 속한 모든 item을 출력하는 Julia 코드

        printon(join(data, ""))

는 음미해볼 만한 부분이다.



삼각형 출력 예제 9
##  Filename: printTriangle9.jl
##            Print a triangle on console.
##
##  Execute: julia printTriangle9.jl
##
##      Date:  2013. 3. 5.
##    Author:  pkim __AT__ scripts ((DOT)) pe ((DOT)) kr

function printTriange()
    start = 8
    data = [" " for i = 1:17]
    last = [" " for i = 1:17]

    data[start + 1] = "*"
    last[start + 1] = "*"
    println(join(data, ""))
    data[start + 1] = " "

    for k = 1:7
        data[start - k + 1] = "*"
        last[start - k + 1] = "*"
        data[start + k + 1] = "*"
        last[start + k + 1] = "*"
        println(join(data, ""))
        data[start - k + 1] = " "
        data[start + k + 1] = " "
    end

    last[start - 8 + 1] = "*"
    last[start + 8 + 1] = "*"
    println(join(last, ""))
end

printTriange()




다음 예제는 수학에서 xy-좌표평면에 점을 찍듯이 논리 구문

             (x + y - 8 == 0) or (y - x + 8 == 0) or (y - 8 == 0)

가 참이 되는 위치에 별(*) 문자를 표시하는 기법으로 작성된 소스 코드이다.



삼각형 출력 예제 10
##  Filename: printTriangle10.jl
##            Print a triangle on console.
##
##  Execute: julia printTriangle10.jl
##
##      Date:  2013. 3. 5.
##    Author:  pkim __AT__ scripts ((DOT)) pe ((DOT)) kr

function printTriange()
    for y = 0:8
        for x = 0:16
            if (x + y - 8 == 0) || (y - x + 8 == 0) || (y - 8 == 0)
                a = "*"
            else
                a = " "
            end
            print(a)
        end
        println("")
    end
end

printTriange()




Posted by Scripter
,