F# 언어 소스:

(* Filename: testHexView_02.fs
 *
 * Compile: fsc testHexView_02.fs
 * Execute: testHexView_02 [filename]
 *
 * Date: 2013. 8. 18.
 *)

open System
open System.IO

let Value (c:char) =
    (int c) - (int 'A') + 1


let toHex n =
    let mutable s = ""
    let x1 = (n &&& 0xF0) >>> 4
    let x2 = n &&& 0xF
    if x1 < 10 then
        s <- s + (sprintf "%c" (char (x1 + (int '0'))))
    else
        s <- s + (sprintf "%c" (char (x1 - 10 + (int 'A'))))
    if x2 < 10 then
        s <- s + (sprintf "%c" (char (x2 + (int '0'))))
    else
        s <- s + (sprintf "%c" (char (x2 - 10 + (int 'A'))))
    s
   
let toHex8 n =
    let mutable s = ""
    let x1 = (n &&& 0xF0000000) >>> 28
    let x2 = (n &&& 0xF000000) >>> 24
    let x3 = (n &&& 0xF00000) >>> 20
    let x4 = (n &&& 0xF0000) >>> 16
    let x5 = (n &&& 0xF000) >>> 12
    let x6 = (n &&& 0xF00) >>> 18
    let x7 = (n &&& 0xF0) >>> 4
    let x8 = n &&& 0xF
    if x1 < 10 then
        s <- s + (sprintf "%c" (char (x1 + (int '0'))))
    else
        s <- s + (sprintf "%c" (char (x1 - 10 + (int 'A'))))
    if x2 < 10 then
        s <- s + (sprintf "%c" (char (x2 + (int '0'))))
    else
        s <- s + (sprintf "%c" (char (x2 - 10 + (int 'A'))))
    if x3 < 10 then
        s <- s + (sprintf "%c" (char (x3 + (int '0'))))
    else
        s <- s + (sprintf "%c" (char (x3 - 10 + (int 'A'))))
    if x4 < 10 then
        s <- s + (sprintf "%c" (char (x4 + (int '0'))))
    else
        s <- s + (sprintf "%c" (char (x4 - 10 + (int 'A'))))
    s <- s + " "
    if x5 < 10 then
        s <- s + (sprintf "%c" (char (x5 + (int '0'))))
    else
        s <- s + (sprintf "%c" (char (x5 - 10 + (int 'A'))))
    if x6 < 10 then
        s <- s + (sprintf "%c" (char (x6 + (int '0'))))
    else
        s <- s + (sprintf "%c" (char (x6 - 10 + (int 'A'))))
    if x7 < 10 then
        s <- s + (sprintf "%c" (char (x7 + (int '0'))))
    else
        s <- s + (sprintf "%c" (char (x7 - 10 + (int 'A'))))
    if x8 < 10 then
        s <- s + (sprintf "%c" (char (x8 + (int '0'))))
    else
        s <- s + (sprintf "%c" (char (x8 - 10 + (int 'A'))))
    s
    
   
[<EntryPoint>]
let main args =

    if args.Length < 1 then
        eprintfn "Usage: testHexView_02 [filename]"
        exit 1
    let fname = args.[0]

    if Directory.Exists(fname) then
          printfn "\"%s\" is a directory." fname
          exit 1

    let file = new FileInfo(fname)
    if not file.Exists then
          printfn "The file \"%s\" does not exist." fname
          exit 1
    let fsize = file.Length

    printfn "The size of the file \"%s\" is %d." fname fsize
    printfn ""

    let fs = IO.File.OpenRead fname
    let currentByte = ref 0
    let mutable n = 0
    let mutable dum = ""
    while (int64 n) < fsize do
        if (n % 16) = 0 then
            printf "%s: " (toHex8 n)
        currentByte := fs.ReadByte()
        if (int !currentByte) < (int ' ') || (int !currentByte) > 0x7F then
            dum <- dum + "."
        else
            dum <- dum + (sprintf "%c" (char !currentByte))
        if (n % 16) = 8 then
            printf "-%s" (toHex (int !currentByte))
        else
            printf " %s" (toHex (int !currentByte))
        if (n % 16) = 15 then
            printfn "  |%s|" dum
            dum <- ""
        n <- n + 1
    if (n % 16) > 0 then
        for i = 1 to (16 - (n % 16)) do
            printf "   "
        printf "  |%s" dum
        for i = 1 to (16 - (n % 16)) do
            printf " "
        printfn "|"
        dum <- ""

    fs.Close()
    printfn "\nRead %d bytes." n

    0

 

실행 예 1> testHexView_02 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> testHexView_02 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 )

 

F# 언어에는 System 모듈에 지수 계산 함수 Math.Pow(double, double) 를 불러서 사용하면 된다. 하지만 차후 필요한 데가 있을 것 같아서 이와 유사한 n 제곱 함수와 n 제곱근 함수를 구현해 보았다.

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

 

1. F# 언어는 닷넷을 목표로 하고 닷넷 위에서 동작하는 (절차적 프로그래밍도 지원하는) 함수형 언어이다.

   하지만, 아래의 소스에서는 함수형 언어의 기능은 거의 사용하지 않앗고, 절차적 언어의 기능을 위주로 사용하였다. 하나의 함수를 구현하는데 함수형 기능과 절차적 기능을 섞어서 사용하는 것은 좋지 않은 습관이다.

2. F# 언어는 (Python 언어 처럼 소스에 들여쓰기 규칙을 철저히 지킨다.

3. F# 언어에서는 상수든 변수든 함수든 처음 선언할 때는 구문 선두에 let 예약어를 반드시 붙인다.

     let a = 2.7                // a 상수
     let mutable b = 5.3    // b 는 변수 
     let g x = x*x             // g 는 함수

아래의 소스 첫 부분에

        let MAX_ITER = 20000
        let M_EPSILON = 1.0e-15

라고 선언하였으니, MAX_ITER 와 M_EPSILON 는 상수로 선언되었다.

4. F# 언어에는 return 이라는 예약어가 없다. 그냥 리턴될 값만 수식으로 표현해 놓으면, F# 컴파일러 fsc(또는 F# 인터프리터 fsci)가 리턴될 값을 알아서 인식하고 처리해 준다.

5. 예외상황 처리를 위해 예외 던지기 구문 raise ... 과 예외 받기 구문 try ... with ...을 이용하였다.

 

 (*
 * Filename: testNthRoot.fs
 *
 *            Approximate square roots, cubic roots and n-th roots of a given number.
 *
 * Compile: fsc --codepage:949 testNthRoot.fs
 * Execute: testNthRoot
 *
 * Date: 2013. 1. 7.
 * Copyright (c) 2013 PH Kim  (pkim __AT__ scripts.pe.kr)
 *)

# light

let MAX_ITER = 20000
let M_EPSILON = 1.0e-15


//
// Compute the n-th root of x to a given scale, x > 0.
//
let rec nPow(a: double, n: int) : double =
    if n > 0 then
        if n = 1 then
            a
        else
            if a = 0.0 || a = 1.0 then
                a
            elif a = -1.0 then
                if n % 2 = 1 then
                    -1.0
                else
                    1.0
            elif a < 0.0 then
                if n % 2 = 1 then
                    -nPow(-a, n)
                else
                    nPow(-a, n)
            else
                let mutable y = 1.0
                for i = 1 to n do
                    y <- y * a
                y
    elif n = 0 then
        1.0
    else      //  when n < 0
        if a = 0.0 then
            raise (new System.InvalidOperationException("Negative powering exception of zero."))
        else
            if n = -1 then
                1.0/a
            else
               1.0/nPow(a, -n)


//
// Compute the n-th root of x to a given scale, x > 0.
//
let rec gPow(a: double, n: int) : double =
    if n > 0 then
        if n = 1 then
            a
        else
            if a = 0.0 || a = 1.0 then
                a
            elif a = -1.0 then
                if n % 2 = 1 then
                    -1.0
                else
                    1.0
            elif a < 0.0 then
                if n % 2 = 1 then
                    -gPow(-a, n)
                else
                    gPow(-a, n)
            else
                let mutable y = 1.0
                let mutable r = a
                let mutable m = 8*4 - 1            //  8*sizeof(int) - 1;
                let mutable one = 1
                for i = 0 to m do
                    if (n &&& one) = 0 then
                        y <- y * 1.0
                    else
                        y <- y * r
                    r <- r*r
                    one <- (one <<< 1)
                y
    elif n = 0 then
        1.0
    else      //  when n < 0
        if a = 0.0 then
            raise (new System.InvalidOperationException("Negative powering exception of zero."))
        else
            if n = -1 then
                1.0/a
            else
                1.0/gPow(a, -n)

 

//
// Compute the n-th root of x to a given scale, x > 0.
//
let rec mPow(a: double, n: int) : double =
    if n > 0 then
        if n = 1 then
            a
        else
            if a = 0.0 || a = 1.0 then
                a
            elif a = -1.0 then
                if n % 2 = 1 then
                    -1.0
                else
                    1.0
            elif a < 0.0 then
                if n % 2 = 1 then
                    -mPow(-a, n)
                else
                    mPow(-a, n)
            else
                let mutable y = 1.0
                let mutable r = a
                let mutable m = n 
                while m > 0 do
                    if (m &&& 0x1) = 1 then
                        y <- y * r
                    r <- r*r
                    m <- (m >>> 1)
                y
    elif n = 0 then
        1.0
    else      //  when n < 0
        if a = 0.0 then
            raise (new System.InvalidOperationException("Negative powering exception of zero."))
        else
            if n = -1 then
                1.0/a
            else
                1.0/mPow(a, -n)

 

//
// Compute the square root of x to a given scale, x > 0.
//
let rec heronSqrt(a: double) : double =
    if a < 0.0 then
        raise (new System.InvalidOperationException("Cannot find the sqrt of a negative number."))
    elif a = 0.0 || a = 1.0 then
        a
    else
        let mutable x1 = a
        let mutable x2 = (x1 + a/x1)/2.0
        let mutable er = x1 - x2
        let mutable counter = 0
        let mutable not_stop = true
        while x1 + er <> x1 && not_stop do
            x1 <- x2
            x2 <- (x1 + a/x1)/2.0
            er <- x1 - x2
            if abs(er) < abs(M_EPSILON*x1) then
                not_stop <- false
            counter <- counter + 1
            if counter > MAX_ITER then
                not_stop <- false
        if counter >= MAX_ITER then
                raise (new System.InvalidOperationException("Inaccurate sqrt exception by too many iterations."))
        x2


//
// Compute the cubic root of x to a given scale, x > 0.
//
let rec newtonCbrt(a: double) : double =
    if a = 0.0 || a = 1.0 || a = -1.0 then
        a
    elif a < 0.0 then
        -newtonCbrt(-a)
    else
        let mutable x1 = a
        let mutable x2 = (2.0*x1 + a/(x1*x1))/3.0
        let mutable er = x1 - x2
        let mutable counter = 0
        let mutable not_stop = true
        while x1 + er <> x1 && not_stop do
            x1 <- x2
            x2 <- (2.0*x1 + a/(x1*x1))/3.0
            er <- x1 - x2
            if abs(er) < abs(M_EPSILON*x1) then
                not_stop <- false
            counter <- counter + 1
            if counter > MAX_ITER then
                not_stop <- false
        if counter >= MAX_ITER then
            raise (new System.InvalidOperationException("Inaccurate cbrt exception by too many iterations."))
        x2


//
// Compute the n-th root of x to a given scale, x > 0.
//
let rec newtonNthRoot(n: int, a: double) : double =
    if n = 0 then
        1.0
    elif n = 1 then
        a
    elif n > 0 then
        if a = 0.0 || a = 1.0 then
            a
        elif a = -1.0 then
            if n % 2 = 1 then
                a
            else
                raise (new System.InvalidOperationException("Cannot find the even n-th root of a negative number."))
        elif a < 0.0 then
            if n % 2 = 1 then
                -newtonNthRoot(n, -a)
            else
                raise (new System.InvalidOperationException("Cannot find the n-th root of a negative number."))
        elif a < 1.0 then
            1.0/newtonNthRoot(n, 1.0/a)
        else
            let mutable x1 = a
            let mutable xn = mPow(x1, n - 1)
            let mutable x2 = ((double n - 1.0)*x1 + a/xn)/(double n)
            let mutable er = x1 - x2
            let mutable counter = 0
            let mutable not_stop = true
            while x1 + er <> x1 && not_stop do
                x1 <- x2
                xn <- mPow(x1, n - 1)
                x2 <- ((double n - 1.0)*x1 + a/xn)/(double n)
                er <- x1 - x2
                if abs(er) < abs(M_EPSILON*x1) then
                    not_stop <- false
                counter <- counter + 1
                if counter > MAX_ITER then
                    not_stop <- false
            if counter >= MAX_ITER then
                raise (new System.InvalidOperationException("Inaccurate n-th root  exception by too many iterations."))
            x2
    else
        if a = 0.0 then
            raise (new System.InvalidOperationException("Cannot find the negative n-th root of zero."))
        else
            1.0/newtonNthRoot(-n, a)


 

 

let mutable x = 16.0
let mutable u = System.Math.Sqrt(x)

printfn "[ Testing heronSqrt(double) ]--------------------"
printfn "x = %g" x
printfn "u = sqrt(%g) = %g" x u
let mutable y = heronSqrt(x)
printfn "y = heronSqrt(%g) = %g" x y
printfn "y*y = %g" (y*y)
printfn ""

x <- 729000000000.0
printfn "x = %g" x
printfn "exp(log(x)/3.0) = %g" (System.Math.Exp (System.Math.Log x)/3.0)
let mutable w = (newtonCbrt x)
printfn "w = newtonCbrt(%g) = %g" x w
printfn "w*w*w = %g"  (w*w*w)
printfn ""

printfn "[ Testing newtonNthRoot(int, double) ]--------------------"
let mutable z = newtonNthRoot(3, x)
printfn "x = %g" x
printfn "z = newtonNthRoot(3, %g) = %g" x z
printfn "z*z*z = %g" (z*z*z)
printfn ""

x <- 12960000000000000000.0
z <- newtonNthRoot(4, x)
printfn "x = %g" x
printfn "z = newtonNthRoot(4, x) = newtonNthRoot(4, %g) =  %g" x z
printfn "z*z*z*z = %g" (z*z*z*z)
printfn ""

x <- 1.0/12960000000000000000.0
z <- newtonNthRoot(4, x)
printfn "x = %g" x
printfn "exp(log(x)/4.0) = %g" (System.Math.Exp (System.Math.Log x)/4.0)
printfn "z = newtonNthRoot(4, x) = newtonNthRoot(4, %g) =  %g" x z
printfn "z*z*z*z = %g" (z*z*z*z)
printfn ""


try
    x <- -4.0
    printfn "[ Test Exception heronSqrt(double) ]--------------------"
    printfn "x = %g" x
    printfn "Calculating heronSqrt(%g)" x
    y <- heronSqrt(x)
    printfn "y = heronSqrt(%g) = %g" x y
    printfn "y*y = %g" (y*y)
    printfn ""
with
    | err -> printfn "%s\nCaught some exception in calculating heronSqrt(%g)" err.Message x
             printfn ""

try
    x <- -4.0
    printfn "[ Test Exception newtonCbrt(double) ]--------------------"
    printfn "x = %g" x
    printfn "Calculating newtonCbrt(%g)" x
    y <- newtonCbrt(x)
    printfn "y = newtonCbrt(%g) = %g" x y
    printfn "y*y*y = %g" (y*y*y)
    printfn ""
with
    | err -> printfn "%s\nCaught some exception in calculating newtonCbrtrt(%g)" err.Message x
             printfn ""


printfn "[ Test calculations by powering ]-----------------------------"
x <- 200.0
z <- newtonNthRoot(10,  x)
printfn "x = %g" x
printfn "exp(log(x)/10.0) = %g"  ((System.Math.Exp (System.Math.Log x))/10.0)
printfn "z = newtonNthRoot(10, x) = newtonNthRoot(10, %g) = %g" x z
printfn "z**10.0 = pow(z, 10.0) = %g" (z**10.0)
printfn ""

x <- 3001.0
z <- newtonNthRoot(99, x)
printfn "x = %g" x
printfn "exp(log(x)/99.0) = %g" (System.Math.Exp(System.Math.Log(x)/99.0))
printfn "z = newtonNthRoot(99, x) = newtonNthRoot(99, %g) = %g" x z
printfn "z**99.0 = pow(z, 99) = %g" (z**99.0)
printfn ""

x <- 3001.0
z <- newtonNthRoot(-99, x)
printfn "x = %g" x
printfn "exp(log(x)/-99.0) = %g" (System.Math.Exp(System.Math.Log(x)/(-99.0)))
printfn "z = newtonNthRoot(-99, x) = newtonNthRoot(-99, %g) = %g" x z
printfn "1.0/z**99.0 = 1.0/pow(z, 99) = %g" (1.0/z**99.0)
printfn ""

printfn "2.1**2.1 = pow(2.1, 2.1) = %g" (2.1**2.1)
printfn "2.1**(-2.1) = pow(2.1, -2.1) = %g" (2.1**(-2.1))
printfn "2.1**2.1 * 2.1**(-2.1) = pow(2.1, 2.1) * pow(2.1, -2.1) = %g" (2.1**2.1 * 2.1**(-2.1))
printfn "2.1**2.1 = exp(2.1*log(2.1)) = %g" (System.Math.Exp(2.1*System.Math.Log(2.1)))
printfn "2.1**(-2.1) = exp(-2.1*log(2.1)) = %g" (System.Math.Exp(-2.1*System.Math.Log(2.1)))
printfn "2.1**2.1 * 2.1**(-2.1) = exp(2.1*log(2.1)) * exp(-2.1*log(2.1)) = %g"  (2.1**2.1 * 2.1**(-2.1))
printfn ""


let mutable k = 301
x <- -1.029
let mutable t1 = nPow(x, k)
let mutable t2 = gPow(x, k)
let mutable t3 = mPow(x, k)
let mutable tt =  System.Math.Pow(x, double k)
printfn "System.Math.Pow(%g, %d) = %g" x k tt
printfn "t1 = nPow(%g, %d) = %g" x k t1
printfn "t2 = gPow(%g, %d) = %g" x k t2
printfn "t3 = mPow(%g, %d) = %g" x k t3
printfn "t1 / t2 = %g" (t1 / t2)
printfn "t1 - t2 = %g" (t1 - t2)
printf "t1 == t2 ? "
if t1 = t2 then printfn "yes"
           else printfn "no"
printfn "t1 / t3 = %g" (t1 / t3)
printfn "t1 - t3 = %g" (t1 - t3)
printf "t1 == t3 ? "
if t1 = t3 then printfn "yes"
           else printfn "no"
printfn "t2 / t3 = %g" (t2 / t3)
printfn "t2 - t3 = %g" (t2 - t3)
printf "t2 == t3 ? "
if t2 = t3 then printfn "yes"
           else printfn "no"
printfn ""


printfn "Done."

 

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

x = 7.29e+11
exp(log(x)/3.0) = 2.43e+11
w = newtonCbrt(7.29e+11) = 9000
w*w*w = 7.29e+11

[ Testing newtonNthRoot(int, double) ]--------------------
x = 7.29e+11
z = newtonNthRoot(3, 7.29e+11) = 9000
z*z*z = 7.29e+11

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

x = 7.71605e-20
exp(log(x)/4.0) = 1.92901e-20
z = newtonNthRoot(4, x) = newtonNthRoot(4, 7.71605e-20) =  1.66667e-05
z*z*z*z = 7.71605e-20

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

[ Test Exception newtonCbrt(double) ]--------------------
x = -4
Calculating newtonCbrt(-4)
y = newtonCbrt(-4) = -1.5874
y*y*y = -4

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

x = 3001
exp(log(x)/99.0) = 1.08424
z = newtonNthRoot(99, x) = newtonNthRoot(99, 3001) = 1.08424
z**99.0 = pow(z, 99) = 3001

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

2.1**2.1 = pow(2.1, 2.1) = 4.74964
2.1**(-2.1) = pow(2.1, -2.1) = 0.210542
2.1**2.1 * 2.1**(-2.1) = pow(2.1, 2.1) * pow(2.1, -2.1) = 1
2.1**2.1 = exp(2.1*log(2.1)) = 4.74964
2.1**(-2.1) = exp(-2.1*log(2.1)) = 0.210542
2.1**2.1 * 2.1**(-2.1) = exp(2.1*log(2.1)) * exp(-2.1*log(2.1)) = 1

System.Math.Pow(-1.029, 301) = -5457.93
t1 = nPow(-1.029, 301) = -5457.93
t2 = gPow(-1.029, 301) = -5457.93
t3 = mPow(-1.029, 301) = -5457.93
t1 / t2 = 1
t1 - t2 = 6.18456e-11
t1 == t2 ? no
t1 / t3 = 1
t1 - t3 = 6.18456e-11
t1 == t3 ? no
t2 / t3 = 1
t2 - t3 = 0
t2 == t3 ? yes

Done.
*)

 

 

 

Posted by Scripter
,

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

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

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

F# 언어에서는 .NET 의 System.Math.Asin(double) 함수를 사용한다.

(*
 * Filename: testArcSine.fs
 *
 * Compile: fsc testArcSine.fs
 * Execute: testArcSine
 *
 * Date: 2013. 1. 2.
 * Copyright (c) pkim _AT_ scripts.pe.kr
 *)

#light

let sin(x: double) : double =
            System.Math.Sin(x)

let asin(x: double) : double =
            System.Math.Asin(x)

let sinh(x: double) : double =
            System.Math.Sinh(x)

let cosh(x: double) : double =
            System.Math.Cosh(x)

let asinh(x: double) : double =
            System.Math.Log(x + sqrt(x*x + 1.0))

let acosh(x: double) : double =
            System.Math.Log(x + sqrt(x*x - 1.0))


let mutable x = -0.9
let mutable y = asin(x)
printfn "y = asin(%.1g) = %.9f" x  y
printfn "sin(y) = sin(%.9f) = %.1g" y (sin y)
printfn ""

x <- 1.1
let mutable u = acosh(x)
printfn "u = acosh(%3.2g) = %.10f" x u

let mutable v = asinh(x)
printfn "v = asinh(%3.2g) = %.10f" x  v

printfn "cosh(u) = cosh(%.10f) = %3.2g" u (cosh u)
printfn "sinh(v) = sinh(%.10f) = %3.2g" 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
,

Visual Studio 2010 을 설치하면 Visual F# 도 함께 설칟히기 때문에 Visual Studio 2008 때 처럼 Visual F# 을 별도로 설치하지 않아도 된다.
2011년 3월 3일에 Visual Studio 2010 Service Pack 1 이 출시되면서 Visual F# 도 업데이트되었다.

FSharp 홈페이지: http://www.fsharp.net/

다음은 간단한 F# Hello 예제이다. 컨솔 출력을 위해 printfn 함수를 쓰고 았다


printfn "Hello"
printfn "안녕하세요?"



저 소스를 파일명 hello.fs (또는 hello.fsx) 로 저장하였다면,

fsc --codepage:949 hello.fs

명령으로 컴파일한다, 그러면 실행파일 hello.exe 가 생성된다,
이를 실핼하면 컨솔에 원하는 글다가 출력된다. (한글도 잘 출력된다.)
컴파일하기 위해서는 일반 명령창 대신 윈도우의

"시작메뉴" -> "Microsoft Visual Studio 2010"
-> "Visual Studio Tools"
-> "Visual Studio 명령 프롬프트(2010)"

하여 열리는 을 열어서 Visual Studio 명령 프롬프트 에서 컴파일하고 실행하는 것이 좋다.

이제 GUI Hello 예제(그래픽 사용자 인터페이스()를 갖는 Hello 예제)를 작성해 보자.
(파일명 HelloWorldFSharpForm.fs 로 저장하였다.)

(* 윈도우 7에서는 폰트, 위젯의 사이즈가 윈도우 XP와 맞지 않아 다소 수정하였다. *)

// Filename: HelloWorldFSharpForm.fs
//
// Compile: fsc --codepage:949 --target:winexe --platform:x86 HelloWorldFSharpForm.fs
// Execute: HelloWorldFSharpForm

open System
open System.Drawing
open System.Windows.Forms

// Create the form and a label objects
let frm = new Form(Text = "Hello world by F#", Width = 400, Height = 170)      // Windows 7 을 위해 수정
let btn = new Button(Text = "인사하기", Width=120, Height=30,                          // Windows 7 을 위해 수정
                    TextAlign = ContentAlignment.MiddleCenter)
let displaybox = new Label(Width=320, Height=35,
                    TextAlign = ContentAlignment.MiddleLeft)
let editbox = new TextBox(Width=200, Height=35,
                    TextAlign = HorizontalAlignment.Left)

// Set ‘Font’ property of the label, textbox, button
btn.Font <- new Font("궁서체", 14.0f)
btn.BackColor <- Color.FromArgb(32, 216, 32)
btn.Location <- new System.Drawing.Point(240, 76)
displaybox.BackColor <- Color.FromArgb(255, 255, 255)
displaybox.Font <- new Font("Vernada", 14.0f, FontStyle.Bold)
displaybox.Location <- new Point(15, 20)
editbox.BackColor <- Color.FromArgb(255, 255, 255)
editbox.Location <- new Point(15, 80)
frm.Controls.Add(btn)
frm.Controls.Add(displaybox)
frm.Controls.Add(editbox)
frm.Show()
let dummy = editbox.Focus()  // Set focus to the textbox


// Function that changes the text of the label for button pressed event
let sayHello (e:EventArgs) =
    let msg = editbox.Text
    let dum = editbox.Focus()  // Set focus to the textbox
    // Set the text at the label
    displaybox.Text <- String.Format("Hello, {0}!", msg)

// Function that changes the text of the label for textbox key pressed event
let greet(ev:KeyEventArgs) =
    if ev.KeyCode = Keys.Enter  then
         let msg = editbox.Text
         let dum = editbox.Focus()  // Set focus to the textbox
         // Set the text at the label
         displaybox.Text <- String.Format("Hello, {0}!", msg)

btn.Click.Add(sayHello)
editbox.KeyDown.Add(greet)

do
  Application.Run(frm)





컴파일은 명령

fsc --codepage:949 --target:winexe HelloWorldFSharpForm.fs

으로 한다다. 생성된 실행파일 HelloWorldFSharpForm.exe 를 실행한다.


다음은 윈도우 7에서 실행한 결과를 캡쳐한 그림이다.



 

Posted by Scripter
,

Visual Studio 2010 을 설치하면 Visual F# 도 함께 설칟히기 때문에  Visual Studio 2008 때 처럼 Visual F# 을 별도로 설치하지 않아도 된다.
2011년 3월 3일에 Visual Studio 2010 Service Pack 1 이 출시되면서 Visual F# 도 업데이트되었다.

               FSharp 홈페이지: http://www.fsharp.net/

다음은 간단한 F# Hello 예제이다. 컨솔 출력을 위해 printfn 함수를 쓰고 았다


printfn "Hello"
printfn "안녕하세요?"



저 소스를 파일명 hello.fs (또는 hello.fsx) 로 저장하였다면,

       fsc --codepage:949 hello.fs

명령으로 컴파일한다, 그러면 실행파일 hello.exe 가 생성된다,
이를 실핼하면 컨솔에 원하는 글다가 출력된다. (한글도 잘 출력된다.)
컴파일하기 위해서는 일반 명령창 대신 윈도우의

      "시작메뉴" -> "Microsoft Visual Studio 2010" 
                     -> "Visual Studio Tools" 
                     -> "Visual Studio 명령 프롬프트(2010)"

하여 열리는 을 열어서 Visual Studio 명령 프롬프트 에서 컴파일하고 실행하는 것이 좋다.

이제 GUI Hello 예제(그래픽 사용자 인터페이스()를 갖는 Hello 예제)를 작성해 보자.
(파일명 HelloWorldFSharpForm.fs 로 저장하였다.)


// Filename: HelloWorldFSharpForm.fs
//
// Compile: fsc --codepage:949 --target:winexe --platform:x86 HelloWorldFSharpForm.fs
// Execute: HelloWorldFSharpForm

open System
open System.Drawing
open System.Windows.Forms

// Create the form and a label objects
let frm = new Form(Text = "Hello world by F#", Width = 360, Height = 160)
let btn = new Button(Text = "인사하기", Width=100, Height=30,
                    TextAlign = ContentAlignment.MiddleCenter)
let displaybox = new Label(Width=320, Height=35,
                    TextAlign = ContentAlignment.MiddleLeft)
let editbox = new TextBox(Width=200, Height=35,
                    TextAlign = HorizontalAlignment.Left)

// Set ‘Font’ property of the label, textbox, button
btn.Font <- new Font("궁서체", 14.0f)
btn.BackColor <- Color.FromArgb(32, 216, 32)
btn.Location <- new System.Drawing.Point(230, 76)
displaybox.BackColor <- Color.FromArgb(255, 255, 255)
displaybox.Font <- new Font("Vernada", 14.0f, FontStyle.Bold)
displaybox.Location <- new Point(15, 20)
editbox.BackColor <- Color.FromArgb(255, 255, 255)
editbox.Location <- new Point(15, 80)
frm.Controls.Add(btn)
frm.Controls.Add(displaybox)
frm.Controls.Add(editbox)
frm.Show()
let dummy = editbox.Focus()  // Set focus to the textbox

// Function that changes the text of the label for button pressed event
let sayHello (e:EventArgs) =
    let msg = editbox.Text
    let dum = editbox.Focus()  // Set focus to the textbox
    // Set the text at the label
    displaybox.Text <- String.Format("Hello, {0}!", msg)

// Function that changes the text of the label for textbox key pressed event
let greet(ev:KeyEventArgs) =
    if ev.KeyCode = Keys.Enter  then
         let msg = editbox.Text
         let dum = editbox.Focus()  // Set focus to the textbox
         // Set the text at the label
         displaybox.Text <- String.Format("Hello, {0}!", msg)

btn.Click.Add(sayHello)
editbox.KeyDown.Add(greet)

do
  Application.Run(frm)




컴파일은 명령

        fsc --codepage:949 --target:winexe HelloWorldFSharpForm.fs

으로 한다. 생성된 실행파일 HelloWorldFSharpForm.exe 를 실행한다.


다음은 실행 결과를 캡쳐한 그림이다.

 

 


 

Posted by Scripter
,

F# 프로그램으로 버튼의  마우스 이벤트를 감지하여 버튼의 색깔을 변경하는 윈도우폼 애플리케이션을 작성해 보았다.  실행시키고 버튼을 클릭할 때마다 버튼의 색깔이 바뀐다.


// Filename: ClickForm5.fs
//
// Compile: fsc --codepage:949 ClickForm5.fs
// Execute: ClickForm5

// Import useful .NET namespaces
open System
open System.Drawing
open System.Windows.Forms

// Create the form and a label objects
let frm = new Form(Text = "버튼 이벤트 핸들러 테스트", Height = 200)
let btn = new Button(Text = "여기를 클릭!", Width=240, Height=60,
                    TextAlign = ContentAlignment.MiddleCenter)
let displaybox = new Label(Width=260, Height=35,
                    TextAlign = ContentAlignment.MiddleLeft)

// Set ‘Font’ property of the label and add label to the form
btn.Font <- new Font("궁서체", 24.0f)
btn.Location <- new System.Drawing.Point(25, 80)
displaybox.BackColor <- Color.FromArgb(255, 255, 255)
displaybox.Font <- new Font("돋움체", 13.0f)
displaybox.Location <- new Point(15, 20)
frm.Controls.Add(btn)
frm.Controls.Add(displaybox)
frm.Show()

// Create random number generator
let rnd = new Random()  

// Function that changes the text of the label and back color of the form
let handleClick (e:EventArgs) =
    let r = rnd.Next(256)
    let g = rnd.Next(256)
    let b = rnd.Next(256)
    // Set the text and the new back color
    btn.Text <- if (btn.Text = "틱!") then "택!" elif (btn.Text = "택!") then "톡!" else "틱!"
    btn.BackColor <- Color.FromArgb(r, g, b)
    displaybox.Text <- String.Format("(R, G, B) = ({0}, {1}, {2})", r, g, b)

btn.Click.Add(handleClick)

do
  Application.Run(frm)



 

                           <실행하여 마우스를 몇 번 클릭한 화면>



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

 

Posted by Scripter
,


F# 프로그램으로 마우스 이벤트를 감지하는 간단한 윈도우폼 애플리케이션을 작성해 보았다.
실행시키고 라벨이 았는 곳을 클릭하면 클릭 횟수가 하나씩 증가한다.
 

(*
 * Filename: TestMouseDownEvent.fs
 *
 *   Compile: fsc TestMouseDownEvent.fs
 *   Execute: TestMouseDownEvent
 *
 *   Date: 2010/07/23
 *   Author: phkim  pkim __AT__ scripts.pe.kr
 *)

open System
open System.Drawing
open System.Windows
open System.Windows.Forms

// Creates the user interface
let frm, lbl = new Form (), new Label()

frm.Width <- 300
frm.Height <- 300
frm.FormBorderStyle <- FormBorderStyle.Fixed3D
frm.Text <- "Test of MouseDown Event"

lbl.Size <- new System.Drawing.Size(200,30)
lbl.TextAlign <- ContentAlignment.MiddleLeft
lbl.Location <- new System.Drawing.Point(20,40)
lbl.Text <- "Click here"
lbl.ForeColor <- Color.DarkGreen
// lbl.Font <- new Font("verdana", 12.0f, FontStyle.Bold)
lbl.Font <- new Font("Lucida Console",10.0f,FontStyle.Bold)
lbl.BackColor <- Color.AliceBlue

frm.Controls.Add(lbl)

let rec loop(count) = async {
  let! args = Async.AwaitEvent(lbl.MouseDown)  // Wait for mouse down
  lbl.Text <- sprintf "Clicks: %d" count
  return! loop(count + 1) }

do
  Async.Start(loop(1))
  Application.Run(frm)




                                  <실행하여 마우스를 몇 번 클릭한 화면>


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

 

Posted by Scripter
,


* 꼬리 재귀호출과 패턴 매칭을 이용하여 구현한 팩토리얼과 피보나치 수열 계산

(*
    Filename: fact.fs
         Rapid factorial and fibonacci seq implementations
         by pattern matching and tail recursive call

    Compile: fsc fact.fs
    Execute: fact

    Date: 2010/07/20
    Author: phkim  pkim __AT__ scripts.pe.kr
*)

#light

let rec fact (n:int) : bigint =
    match n with
    | 0 | 1    -> 1I
    | k        -> (bigint k) * (fact (k-1))

let factorial n =
    let rec loop acc k =
          match k with
          | 0 -> acc
          | _ -> loop (acc*(bigint k)) (k - 1)
    loop 1I n

let fibonacci n =
    let rec loop a b k =
          match k with
          | 0 -> a
          | _ -> loop (a + b) a (k - 1)
    loop 0I 1I n

let a = 30000
let b = 200000
printfn "Factorial(%O) has %O digits" a ((sprintf "%O" (factorial a)).Length)
printfn "Fibonacci(%O) has %O digits" b ((sprintf "%O" (fibonacci b)).Length)
(*
    Expected result:
    Factorial(30000) has 121288 digits
    Fibonacci(200000) has 41798 digits
*)

 

 


 

Posted by Scripter
,

F# 언어에서 int 타입과 bigint 타입을 상호변환 하는 것은 의외로 쉽다.


명령 프롬프트> fsi

Microsoft (R) F# 2.0 Interactive build 2.0.0.0
Copyright (c) Microsoft Corporation. All Rights Reserved.

For help type #help;;
> let a = 100I;;
val a : System.Numerics.BigInteger = 100I

> let b = int a;;
val b : int = 100

> let c = bigint b;;
val c : System.Numerics.BigInteger = 100I
> b**5;;
  b**5;;
  ^
stdin(13,1): error FS0001: The type 'int' does not support any operators named '
Pow'

> a**5;;
val it : System.Numerics.BigInteger = 10000000000I

> c**5;;
val it : System.Numerics.BigInteger = 10000000000I

> a**5 = c**5;;
val it : bool = true

let k = int "320";;
val k : int = 320

> let m = bigint "320";;

  let m = bigint "320";;
  --------^^^^^^^^^^^^

stdin(19,9): error FS0041: No overloads match for method 'BigInteger'. The avail
able overloads are shown below (or in the Error List window).
Possible overload: 'System.Numerics.BigInteger()'.
Possible overload: 'new : x:int -> System.Numerics.BigInteger'.
Possible overload: 'new : x:int64 -> System.Numerics.BigInteger'.
Type constraint mismatch. The type
    string
is not compatible with type
    int
The type 'string' is not compatible with the type 'int'
Type constraint mismatch. The type
    string
is not compatible with type
    int64
The type 'string' is not compatible with the type 'int64'

> let m = new System.Numerics.BigInteger("320");;

  let m = new System.Numerics.BigInteger("320");;
  --------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

stdin(22,9): error FS0041: No overloads match for method 'BigInteger'. The avail
able overloads are shown below (or in the Error List window).
Possible overload: 'System.Numerics.BigInteger()'.
Possible overload: 'new : x:int -> System.Numerics.BigInteger'.
Possible overload: 'new : x:int64 -> System.Numerics.BigInteger'.
Type constraint mismatch. The type
    string
is not compatible with type
    int
The type 'string' is not compatible with the type 'int'
Type constraint mismatch. The type
    string
is not compatible with type
    int64
The type 'string' is not compatible with the type 'int64'

> let m = "320" |> System.Numerics.BigInteger.Parse;;
val m : System.Numerics.BigInteger = 320I


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

 

Posted by Scripter
,


정의 (소수와 합성수)
    1보다 큰 양의 정수 n에 대하여
    (i) n = a * b 를 만족하고 1보다 큰 두 양의 정수 a와 b가 존재하면,
        n을 합성수(合成數, composite number)라고 한다. 참고로 이 경우,
        a, b 중에 적어도 하나는 sqrt(n) 보다 작거나 같다.
        합성수의 예로는 4, 6, 9, 24, 143 등이 있다.
    (ii) n = a * b 를 만족하고 1보다 큰 두 양의 정수 a와 b가 존재하지 않으면,
         즉 n을 두 양의 정수의 곱으로 표현하는 방법이 1*n과 n*1 두 가지 뿐이면,
         n을 소수(素數, prime number)라고 한다.  소수의 예로는 2, 3, 5, 7, 11 등이 있다.
         n이 소수인지 아닌지 확인하려면, 
         n을 2 보다 크거나 같고 sqrt(n) 보다 작거나 같은 모든 정수로 나누어 본다.
         이 경우 언제나 나누어 떨어지지  않으면 n은 소수이고, 그렇지 않으면 n은 합성수이다.
    

우선 다음의 F# 소스 코드는 명령행 인자로 전달 받은 양의 정수 n을
2 및 3, 5, 7, ... , sqrt(n) 이하의 홀수들로 나누어 보아 n이 합성수인지 아닌지
확인하는 애플리케이션 소스이다. 확인하는데 걸린 경과 시간도 알려준다.

(*
 *  Filename: DivideEach.fs
 *
 *  Purpose:  Determine whether the given integer is a prime or not.
 *
 *  Compile: fsc DivideEach.fs
 *  Execute: DivideEach [integer]
 *
 *     Date:  2010/07/17
 *   Author:  PH Kim   [ pkim ((AT)) scripts.pe.kr ]
 *)

(*
  Execution Examples:
      Prompt> DivideEach 1234567812343
      1234567812343 = 1 * 1234567812343
      1234567812343 is a prime
      Elapsed time: 0.750000 sec

      Prompt> DivideEach 9999994200000841
      9999994200000841 = 99999971 * 99999971
      9999994200000841 is a not prime
      Elapsed time: 121.140000 sec

      Prompt> DivideEach 18446744073709551617
      18446744073709551617 = 274177 * 67280421310721
      18446744073709551617 is a not prime
      Elapsed time: 0.218000 sec

      Prompt> DivideEach 10023859281455311421
      10023859281455311421 = 1308520867 * 7660450463
      10023859281455311421 is a not prime
      Elapsed time: 1471.500000 sec
/*)


#light

open System

let mutable n = 10006099720301I

// Begin here
let cmdArgs = System.Environment.GetCommandLineArgs()
if (Array.length cmdArgs > 1) then
    // n <- new Numerics.BigInteger(cmdArgs.[1])
    n <- (cmdArgs.[1]) |> Numerics.BigInteger.Parse


let mutable z = n / 2I
if n = 2I*z then
    printfn "%O = %O * %O" n  2I z

let time1 = DateTime.UtcNow

let mutable d = 1I
let mutable k = 3I
let mutable cont_flag = true
while (k*k <= n && cont_flag) do
    z <- n / k
    if n = k*z then
        d <- k
        cont_flag <- false
    else
        k <- k + 2I

let time2 = DateTime.UtcNow
let elapsed = float (int64 (time2 - time1).TotalMilliseconds) / 1000.0

printfn "%O = %O * %O" n d (n/d)
if d = 1I then
    printfn "%O is a prime" n
else
    printfn "%O is a not prime" n

printfn "Elapsed time: %f sec" elapsed



이제 다음은 정수의 인수분해 능력이 뛰어난  Pollard의 rho 방법(일명 거북이와 토끼 알고리즘, tortoise-hair algorithm)을 구현한  F# 소스 코드이다. 이 알고리즘은 소수에 대해서는 시간이 많이 걸리지만, 합성수에 대해서는 시간이 매우 적게 걸린다는 것이 특징이다.

(*
 *  Filename: PollardRho.fs
 *
 *  Purpose:  By using the pollard rho method,
 *            determine whether the given integer is a prime or not.
 *
 *      See:  http://en.wikipedia.org/wiki/Pollard%27s_rho_algorithm
 *            http://en.wikipedia.org/wiki/Floyd%27s_cycle-finding_algorithm#Tortoise_and_hare#
 *
 *  Compile: fsc PollardRho.fs
 *  Execute: PollardRho [integer]
 *
 *     Date:  20010/07/18
 *   Author:  PH Kim   [ pkim ((AT)) scripts.pe.kr ]
 *)

(*
  Execution Examples:
      Prompt> PollardRho 1234567812343
      Try first the Pollard rho algorithm with c = 2
      d = 1234567812343, count = 466951
      Try second the Pollard rho algorithm with c = 3
      d = 1, count = 1111112
      Try third the Pollard rho algorithm with c = 1
      d = 1234567812343, count = 799441
      1234567812343 = 1234567812343 * 1
      Elapsed time: 63.640000 sec

      Prompt> PollardRho 9999994200000841
      Try first the Pollard rho algorithm with c = 2
      d = 99999971, count = 3593
      9999994200000841 = 99999971 * 99999971
      Elapsed time: 0.281000 sec

      Prompt> PollardRho 18446744073709551617
      Try first the Pollard rho algorithm with c = 2
      d = 274177, count = 1028
      18446744073709551617 = 274177 * 67280421310721
      Elapsed time: 0.187000 sec

      Prompt> PollardRho 10023859281455311421
      Try first the Pollard rho algorithm with c = 2
      d = 1308520867, count = 20350
      10023859281455311421 = 1308520867 * 7660450463
      Elapsed time: 0.968000 sec
*)


#light

open System

let f (x : bigint) (c : bigint) (n : bigint) =
    (x*x + c) % n

let g (x : bigint) (c : bigint) (n : bigint) =
    f (f x c n) c n

let gcd x  y =
    let mutable a = abs x
    let mutable b = abs y
    if b = 0I then
        a
    else
        while b <> 0I do
            let t = a % b
            a <- b
            b <- t
        a

let pollardRho (n : bigint) =
    let mutable c = 2I
    let mutable x = 1I
    let mutable y = 1I
    let mutable d = 1I
    let mutable savedX = x
    let mutable count = 0I
    printfn "Try first the Pollard rho algorithm with c = %O" c
    let mutable cont_flag = true
    while d = 1I && count*count <= n && cont_flag do
        x <- f x c n
        if x = savedX then
            printfn "It is cyclic.  x = %O" x
            cont_flag <- false
        else
            y <- g y c n
            d <- gcd (abs (x - y)) n
        count <- count + 1I

    printfn "d = %O, count = %O" d count
    if d > 1I && d < n then
        d
    else
        c <- 3I
        x <- 1I
        y <- 1I
        d <- 1I
        savedX <- x
        count <- 0I
        printfn "Try second the Pollard rho algorithm with c = %O" c
        cont_flag <- true
        while d = 1I && count*count <= n do
            x <- f x c n
            if x = savedX then
                 printfn "It is cyclic.  x = %O" x
                 cont_flag <- false
            else
                 y <- g y c n
                 d <- gcd (abs(x - y)) n
                 count <- count + 1I

        printfn "d = %O, count = %O" d count
        if d > 1I && d < n then
            d
        else
            c <- 1I
            x <- 1I
            y <- 1I
            d <- 1I
            savedX <- x
            count <- 0I
            printfn "Try third the Pollard rho algorithm with c = %O" c
            let mutable cont_flag2 = true
            while d = 1I && count*count <= n do
                x <- f x c n
                if x = savedX then
                    printfn "It is cyclic.  x = %O" x
                    cont_flag2 <- false
                else
                    y <- g y c n
                    d <- gcd (abs(x - y)) n
                    count <- count + 1I

            printfn "d = %O, count = %O" d count
            d


// Begin here
let mutable n = 9991I

let cmdArgs = System.Environment.GetCommandLineArgs()
if (Array.length cmdArgs > 1) then
    n <- (cmdArgs.[1]) |> Numerics.BigInteger.Parse

let time1 = DateTime.UtcNow
let k = pollardRho n
let time2 = DateTime.UtcNow
let elapsed = float (int64 (time2 - time1).TotalMilliseconds) / 1000.0

let z = n/k
if n = k*z then
    printfn "%O = %O * %O" n k z

printfn "Elapsed time: %f sec" elapsed


 

Posted by Scripter
,