Python 2.7.8 에 PyGTK 를 설치한 후, 

GTK 와 PyGTK 의 버전 알아내기

 

1. 윈도우에서 32 비트 Python 2.7.8 에 PyGTK 밑 모든 관련 파일을 한 번에 내려받아 설치하기:

http://ftp.gnome.org/pub/GNOME/binaries/win32/pygtk/2.22/pygtk-all-in-one-2.22.6.win32-py2.7.msi

 

프롬프트> python
Python 2.7.8 (default, Jun 30 2014, 16:03:49) [MSC v.1500 32 bit (Intel)] on win
32
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.version
'2.7.8 (default, Jun 30 2014, 16:03:49) [MSC v.1500 32 bit (Intel)]'
>>> import pygtk
>>> pygtk.require('2.0')
>>> import gtk
>>> gtk.gtk_version
(2, 22, 1)
>>> gtk.pygtk_version
(2, 22, 0)

 

2. 윈도우에서 64 비트 Python 2.7.8 에 PyGTK 밑 관련 파일들을 내려받아 설치하기:

1) http://www.gtk.org/download/win64.php 에사 하나의 파일로 압축 2.22 번정르 내려 받아 폴더 C:\gtk2 에 압축  해제한후 C:\gtk2\bin 을 환경변수 PATH 에 걸어 둔다.

2) http://www.lfd.uci.edu/~gohlke/pythonlibs/#pygtk 에서 64 비트용 pygtk, pygobject, py2cairo 들을 각각 내려받아 각가의 exe 파일을 더블클릭하여 설치한다.

 

프롬프트> python
Python 2.7.8 (default, Jun 30 2014, 16:08:48) [MSC v.1500 64 bit (AMD64)] on win
32
Type "help", "copyright", "credits" or "license" for more information.
>>> import pygtk
>>> pygtk.require("2.0")
>>> import gtk
>>> gtk.gtk_version
(2, 22, 1)
>>> gtk.pygtk_version
(2, 22, 0)
>>> import sys
>>> sys.version
'2.7.8 (default, Jun 30 2014, 16:08:48) [MSC v.1500 64 bit (AMD64)]'

 

* PyGTK 의 태스트 예제: button.py

#!/usr/bin/env python

# example-start buttons buttons.py

import pygtk
pygtk.require('2.0')
import gtk

# Create a new hbox with an image and a label packed into it
# and return the box.

def xpm_label_box(parent, xpm_filename, label_text):
    # Create box for xpm and label
    box1 = gtk.HBox(False, 0)
    box1.set_border_width(2)

    # Now on to the image stuff
    image = gtk.Image()
    image.set_from_file(xpm_filename)

    # Create a label for the button
    label = gtk.Label(label_text)

    # Pack the pixmap and label into the box
    box1.pack_start(image, False, False, 3)
    box1.pack_start(label, False, False, 3)

    image.show()
    label.show()
    return box1

class Buttons:
    # Our usual callback method
    def callback(self, widget, data=None):
        print "Hello again - %s was pressed" % data

    def __init__(self):
        # Create a new window
        self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)

        self.window.set_title("Image'd Buttons!")

        # It's a good idea to do this for all windows.
        self.window.connect("destroy", lambda wid: gtk.main_quit())
        self.window.connect("delete_event", lambda a1,a2:gtk.main_quit())

        # Sets the border width of the window.
        self.window.set_border_width(10)

        # Create a new button
        button = gtk.Button()

        # Connect the "clicked" signal of the button to our callback
        button.connect("clicked", self.callback, "cool button")

        # This calls our box creating function
        box1 = xpm_label_box(self.window, "info.xpm", "cool button")

        # Pack and show all our widgets
        button.add(box1)

        box1.show()
        button.show()

        self.window.add(button)
        self.window.show()

def main():
    gtk.main()
    return 0    

if __name__ == "__main__":
    Buttons()
    main()

 

프롬프트> python button.py

 

 

 

Posted by Scripter

댓글을 달아 주세요

 

Scala 언어 소스:

/*
 * Filename: testHexView_03.scala
 *
 *    Purpose: Show the hexadecimal values of the given file.
 *
 * Compile: scalac -deprecation -d . testHexView_03.scala
 * Execute: scala testHexView_03 [filename]
 *
 * Date: 2013. 8. 18.
 */

import java.io._

object testHexView_03 {

    def printUsage() {
        println("Usage: scala testHexView_03 [filename]")
    }

    def toHex(n: Int) : String = {
        var s = ""
        var x1 = (n & 0xF0) >> 4
        var x2 = n & 0xF
        if (x1 < 10) {
            s = s + "%c".format(('0' + x1) toChar)
        }
        else {
            s = s + "%c".format('A' + (x1 - 10))
        }
        if (x2 < 10) {
            s = "%s%c".format(s, ('0' + x2) toChar)
        }
        else {
            s = s + "%c".format('A' + (x2 - 10))
        }
        return s
    }

    def toHex8(n: Int) : String = {
        var s = ""
        var x1 = (n & 0xF0000000) >> 28
        var x2 = (n & 0xF000000) >> 24
        var x3 = (n & 0xF00000) >> 20
        var x4 = (n & 0xF0000) >> 16
        var x5 = (n & 0xF000) >> 12
        var x6 = (n & 0xF00) >> 8
        var x7 = (n & 0xF0) >> 4
        var x8 = n & 0xF
        if (x1 < 10) {
            s = s + "%c".format(('0' + x1) toChar)
        }
        else {
            s = s + "%c".format('A' + (x1 - 10))
        }
        if (x2 < 10) {
            s = "%s%c".format(s, ('0' + x2) toChar)
        }
        else {
            s = s + "%c".format('A' + (x2 - 10))
        }
        if (x3 < 10) {
            s = "%s%c".format(s, ('0' + x3) toChar)
        }
        else {
            s = s + "%c".format('A' + (x3 - 10))
        }
        if (x4 < 10) {
            s = "%s%c".format(s, ('0' + x4) toChar)
        }
        else {
            s = s + "%c".format('A' + (x4 - 10))
        }
        s = s + " "
        if (x5 < 10) {
            s = "%s%c".format(s, ('0' + x5) toChar)
        }
        else {
            s = s + "%c".format('A' + (x5 - 10))
        }
        if (x6 < 10) {
            s = "%s%c".format(s, ('0' + x6) toChar)
        }
        else {
            s = s + "%c".format('A' + (x6 - 10))
        }
        if (x7 < 10) {
            s = "%s%c".format(s, ('0' + x7) toChar)
        }
        else {
            s = s + "%c".format('A' + (x7 - 10))
        }
        if (x8 < 10) {
            s = "%s%c".format(s, ('0' + x8) toChar)
        }
        else {
            s = s + "%c".format('A' + (x8 - 10))
        }
        return s
    }


    def main(args: Array[String]) {
            if (args.length < 1) {
                printUsage()
                System.exit(1)
            }

            var fname : String = args(0)

            var infile : File = new File(fname);
            if  (!infile.exists()) {
                 System.out.println("The file \"" + fname + "\" does not exist.");
                 System.exit(1);
            }

            if (!infile.canRead()) {
                 System.out.println("The file \"" + fname + "\" is not allowed to be read.");
                 System.exit(1);
            }   

            if  (infile.isDirectory()) {
                 System.out.println("\"" + fname + "\" is a directory.");
                 System.exit(1);
            }


            val is = new FileInputStream(fname)
            val cnt = is.available

            var lines = new Array[String](19)
            var b = new Array[Byte](1)

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

            var n = 0
            var dum = ""
            while (n < cnt) {
                if (n % 16 == 0) {
                    printf("%s: ", toHex8(n))
                }
                is.read(b)
                if (n % 16 == 8) {
                    printf("-%s", toHex(b(0) toInt))
                }
                else {
                    printf(" %s", toHex(b(0) toInt))
                }
                if ((b(0) toInt) < (' ' toInt) || (b(0) toInt) > 0x7F) {
                    dum = dum + "."
                }
                else {
                    dum = dum + "%c".format(b(0) toChar)
                }
                if (n % 16 == 15) {
                    printf("  |%s|\n", dum)
                    dum = ""
                }
                n += 1
            }
            if (n % 16 > 0) {
                for (j <- 1 to 16 - (n % 16)) {
                    printf("   ")
                }
                printf("  |%s", dum)
                for (j <- 1 to 16 - (n % 16)) {
                    printf(" ")
                }
                printf("|\n", dum)
                dum = ""
            }
            printf("\nRead %d bytes.\n", n)

            is.close()
    }
}

 

 

실행 예 1> scala testHexView_03 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> scala testHexView_03 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

댓글을 달아 주세요

 

Ruby 언어 소스:

# Filename: testHexView_02.rb
#
# Execute: ruby testHexView_02.rb [filename]

def toHex(b)
    s = ""
    x1 = (b & 0xF0) >> 4
    x2 = b & 0x0F
    if x1 < 10 then
        s += (x1 + '0'[0].ord).chr
    else
        s += ((x1 - 10) + 'A'.ord).chr
    end
    if (x2 < 10)
        s += (x2 + '0'.ord).chr
    else
        s += ((x2 - 10) + 'A'.ord).chr
    end
    return s
end

def toHex8(n)
    s = ""
    x1 = (n & 0xF0000000) >> 28
    x2 = (n & 0xF000000) >> 24
    x3 = (n & 0xF00000) >> 20
    x4 = (n & 0xF0000) >> 16
    x5 = (n & 0xF000) >> 12
    x6 = (n & 0xF0) >> 8
    x7 = (n & 0xF0) >> 4
    x8 = n & 0x0F
    if x1 < 10 then
        s += (x1 + '0'.ord).chr
    else
        s += ((x1 - 10) + 'A'.ord).chr
    end
    if x2 < 10 then
        s += (x2 + '0'.ord).chr
    else
        s += ((x2 - 10) + 'A'.ord).chr
    end
    if x3 < 10 then
        s += (x3 + '0'.ord).chr
    else
        s += ((x3 - 10) + 'A'.ord).chr
    end
    if x4 < 10 then
        s += (x4 + '0'.ord).chr
    else
        s += ((x4 - 10) + 'A'.ord).chr
    end
    s += " "
    if x5 < 10 then
        s += (x5 + '0'.ord).chr
    else
        s += ((x5 - 10) + 'A'.ord).chr
    end
    if x6 < 10 then
        s += (x6 + '0'.ord).chr
    else
        s += ((x6 - 10) + 'A'.ord).chr
    end
    if x7 < 10 then
        s += (x7 + '0'.ord).chr
    else
        s += ((x7 - 10) + 'A'.ord).chr
    end
    if x8 < 10 then
        s += (x8 + '0'.ord).chr
    else
        s += ((x8 - 10) + 'A'.ord).chr
    end
  
    return s
end


fname = ARGV[0]
begin
    if fname == nil then
        print "Usage: ruby testHexView_02.rb [filename]\n"
        exit(1)
    elsif not File.exist?(fname) then
        print "The file '%s' does not exist.\n" % fname
        exit(1)
    elsif File.directory?(fname) then
        print "%s is a directory\n" % fname
        exit(1)
    end

    fsize = File.size?(fname)
    if fsize != nil then
        print "The size of the file \"%s\" is %d.\n" % [fname, fsize]
        if fsize == 0 then
            exit(1)
        end
    end
    puts
    file2 = File.open(fname, "r")

    n = 0
    dum = ""
    fsize.times {
        if n % 16 == 0 then
            print "%s: " % toHex8(n & 0xFFFFFFFF)
        end
             
        if n % 16 != 8 then
            print " "
        else
            print "-"
        end

        a = file2.read(1)
        print "%s" % toHex(a.ord.to_i & 0xFF)
               
        if a.ord.to_i < ' '.ord.to_i or a.ord.to_i > 0x7F then
            dum += "."
        else
            dum += a
        end
               
        if n > 0 and n % 16 == 15 then
            print "  |%s|\n" % dum
            dum = ""
        end             

        n += 1
    }

    if n > 0 and n % 16 > 0 then
        (16 - (fsize % 16)).times {
            print "   "
        }
        print "  |%s" %dum
        (16 - (fsize % 16)).times {
            print " "
        }
        print "|\n"
        dum = ""
    end

    file2.close
    puts
    print "Read %d bytes\n" % n
rescue => err
    puts "Exception: #{err}"
    err
end

 

예 1

Ruby로 실행하기> ruby testHexView_02.rb temp_1.bin
JRuby로 실행하기> jruby testHexView_02.rb 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

Ruby로 실행하기> ruby testHexView_02.rb myFile.ser
JRuby로 실행하기> jruby testHexView_02.rb myFile.ser
C:\test\java7>ruby testHexView_02.rb 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

댓글을 달아 주세요

Clojure 는 Rich Hickey 씨가 만든 Lisp 계열의 함수형 언어로서 자바가상기계(JVM) 위에서의 동작을 목표로 하고 있다. (CLR과 자바스트크립트에서 동작하는 Clojure 는 각각 별도의 프로젝트로 개발되고 있다,) 다른 Lisp 아류와는 달리, Clojure 는 소스 코드를 데이터로 본다. Clojure 는 철저하게 값(value)은 수정 불가 값(immutable value) 만을 견지하고 ,특히 다중 쓰레드 환경에서 더 견고한 프로그램을 개발이 용이하도록 촉진한다.

 

zip 파일을 압축 풀어서 d:\clojure-1.4.0 이 Clojure 기본 폴더가 되도록 옮긴다.

* Clojure 실행을 위한 일괄(bat) 파일 작성

명령 프롬프트> more clojure.bat
@echo off
java -cp d:\clojure-1.4.0\clojure-1.4.0.jar clojure.main
@echo on

 

* Clojure 실행

명령 프롬프트> clojure
Clojure 1.4.0
user=> (+ 1 2 3)
6
user=> (javax.swing.JOptionPane/showMessageDialog nil "Hello World")
nil
user=> (javax.swing.JOptionPane/showMessageDialog nil "안녕하세요?")
nil
user=> (str "aaa" 25 "BC")
"aaa25BC"
user=> (str ["aaa", "111"])
"[\"aaa\" \"111\"]"
user=> (str (+ 25 27))
"52"
user=> (javax.swing.JOptionPane/showMessageDialog nil (str "길동씨 안녕하세요?\n" "  1.1 + 2.2 + 3.3 = " (+ 1.1 2.2 3.3) "\n입니다."))
nil
user=> ^Z

 

(참고. 윈도우XP 의 경우 clojure 셸에서 한글이 입력되지 않아 다른 곳에서 한글을 입력한 후 붙여 넣기하였다. 윈도우 7의 경우 clojure 셸에서 한글 입력이 잘된다.)

+, -, *, / 연산 기호가 배열된 수치 들을 모두 계산해 주듯이 str 은 배열된 스트링을 모두 붙이기(concatenation)한다. 스트링이 아닌 것은 스트링으로 변환(자바의 toString() 메소드 적용)하여 붙이기 한다.

아래는 위의 명령으로 나타난 메세지 창 (한글도 잘 됨)

 

 

 

 

 

다음은 .NET 용 Clojure 인 clojure-clr-mater 를 Visual Studio 2010 에서 빌드한 후 실행 파일 Clojure.Main.exe 를 명령 프롬픙에서  실행한 경우이다.

명령 프롬프트> Clojure.Main
Clojure 1.5.0-master-SNAPSHOT
user=> (System.Reflection.Assembly/LoadWithPartialName "System.Windows.Forms")
#<RuntimeAssembly System.Windows.Forms, Version=4.0.0.0, Culture=neutral, Public
KeyToken=b77a5c561934e089>
user=> (import (System.Windows.Forms MessageBox))
System.Windows.Forms.MessageBox
user=> (MessageBox/Show (str "Hi from clojure-clr! " "9 x 9 = " (* 9 9) " 안녕하시렵니까? ") "Clojure-CLR Dialog")
OK
user=> ^Z

 

 

 

 

'소개와 설치 > Clojure' 카테고리의 다른 글

Clojure 설치하고 테스트하기  (0) 2013.02.10
Posted by Scripter

댓글을 달아 주세요

 

Lisp 언어의 변종인 주요 후계자 언어로는 보통 Common Lisp 과 Scheme 두 가지가 꼽힌다.

Scheme 언어는 1975년~1980년 기간에 MIT 인공지능 연구실에서 Guy L. Steels 와 Gerald 와 Jay Sussman 에 의해 개발되었으며, RnRS(Revised Report on the Algorithmic Language Scheme) 라는 이름으로 그 표준이 공개되어 왔다. (여기서 n은 숫자) R5RS는 1998년에 발표되었으며 가장 널리 쓰여진 Scheme 이며, R6RS 는 2007년 8월 27일에 발표되었고, R7RS 가 최근 2012년 12월 10일에 발표 되었다. (이 중 R6RS 는 Sheme 의 최소 설계 철학(minimalist design philosophy) 에 관해 논쟁이 좀 있었던 버전이다.)

 

1. 윈도우용 Scheme 9.1.1 설치 후 명령 프롬프트에서 실행하기

 

명령 프롬프트> set PATH=d:\scheme\bin;%PATH%

명령 프롬프트> set MITSCHEME_BAND=d:\scheme\lib\all.com

명령 프롬프트> mit-scheme

(또는 명령 프롬프트> mit-scheme --edit )

(또는 명령 프롬프트> mit-scheme --edwin )

 

* 소스 파일명: hello.scm  (Scheme 설치 후 테스트 파일. 환경변수 MITSCHEME_BAND 가 필요)

(define (greet msg)
  (write (string-append "Hello, " msg "\n"))
  (newline)
  (display (string-append "Hello, " msg "\n")))

(greet "world!")

 

명령 프롬프트> mit-scheme

 

mit-scheme 을 실행시킨 후, Scheme 창에서 명령

        (cf "hello")

        (load "hello")

        (exit)

 을 차례로 내린다.

 

* 소스 파일명: fact.scm  (Scheme 설치 후 테스트 파일. 환경변수 MITSCHEME_BAND 가 필요)

(define (fact n)
  (if (= n 0)
      1
      (* n (fact (- n 1)))))

 

명령 프롬프트> mit-scheme

mit-scheme 을 실행시킨 후, Scheme 창에서 명령

        (cf "fact.scm")

        (load "fact")

        (fact 100)

        (exit)

 을 차례로 내린다.

 

2. 윈도우에 설치된 Cygwin 에서 Scheme 실행하기

cywin 에는 Scheme 은 설치가 안되지만, CHICKEN Scheme 가 이미 설치되어 있다. CHICKEN Scheme 은 R5RS 이다. (cygwin 설치시 함께 설치된 것은 다소 낮은 버전 2008년 3,4,0 이다.)

csc 는 컴파일 명령이고, csi 는 대화형 인터프리터 명령이다.

$ which chicken

$ which csc        (csc 는 C# 캄파일러가 아니고, CHICKEN Scheme Compiler 이다.)

$ which csi

$ which scsh      (scsh 는 CHICKEN Scheme 과는 상관없고,  Sheme shell script 해석기이다.)

 

* 소스 내용 확인

$ more hello.scm
(define (greet msg)
  (write (string-append "Hello, " msg "\n"))
  (newline)
  (display (string-append "Hello, " msg "!\n")))

(greet "world!")

 

* 대화형 인터프리터 실행

$ csi

CHICKEN
(c)2008 The Chicken Team
(c)2000-2007 Felix L. Winkelmann
Version 3.4.0 - windows-cygwin-x86      [ manyargs dload ptables applyhook ]
SVN rev. 11987  compiled 2008-10-09 on NTXCN1042727 (CYGWIN_NT-5.1)

#;1> (load "hello.scm")
; loading hello.scm ...
"Hello, world!\n"
Hello, world!
#;2> (greet "안녕?")
"Hello, 안녕?\n"
Hello, 안녕?
#;3> (greet "CHICKEN Scheme")
"Hello, CHICKEN Scheme\n"
Hello, CHICKEN Scheme
#;4> (exit)

 

* 컴파일 후 실행

$ csc -o hello hello.scm

$ ./hello
"Hello, world!\n"
Hello, world!

 

* 소스 내용 확인

$ more fact.scm
(define (fact n)
  (if (= n 0)
      1
      (* n (fact (- n 1)))))

* 대화형 인터프리터 실행

$ csi

CHICKEN
(c)2008 The Chicken Team
(c)2000-2007 Felix L. Winkelmann
Version 3.4.0 - windows-cygwin-x86      [ manyargs dload ptables applyhook ]
SVN rev. 11987  compiled 2008-10-09 on NTXCN1042727 (CYGWIN_NT-5.1)

#;1> (load "fact.scm")
; loading fact.scm ...
#;2> (fact 10)
3628800
#;3> (exit)

 

'소개와 설치 > Scheme' 카테고리의 다른 글

함수형 언어 Scheme 의 소개와 설치  (0) 2013.02.09
Posted by Scripter

댓글을 달아 주세요

OCaml 3.12.1 윈도우 용 설치 시 주의할 점 (PATH 가 바뀌는 버그)

OCaml 3.12.1 윈도우 용 인스톨러가 하는 일 중에 나쁜 일(사용자를 난감하게 하는 일)이 하나 있다. 설치 되고 나면 시스템 환경변수 중에 OCAMLLIB 를 잡아주는 것은 좋은데, PATH 를 완전 바꾸어 버린다. 원래 있던 PATH 값은 완전 사라지고, 설치된 OCaml 의 bin 폴더의 경로명과  emacs 아래의 bin 폴더의 경로명만 남아 있다. 그러므로 OCaml 3,12,1 윈도우 용을 설치하기 전에는 시스템 환경변수 PATH 의 값을 미리 별도로 저장한 다음, 설치가 끝나면 PATH 의 값을 (뿥여 넣기하여) 복구시켜 주어야 한다.

상세 내용 참조

 

아래는 http://protz.github.com/ocaml-installer/ 에 쓰여진 글

Other versions

 

윈도우에 OCaml 3.12.1 을 설치 후 바꾸어야 하는 것 한 가지 더

OCaml 3.12.1 의 설치 폴더 아래에 bin 폴더 내에 파일명 ocamlmktop 을 파일명  ocamlmktop.exe 으로 바꾸어야 함. (파일명에 확장명 .exe 를 추가) 이 파일은 ocamlyacc, ocamllex 와 함깨 쓰이기도 한다. 컴파일되어 생성된 실행 파일이 OCaml 의 toplevel 위에서 실행되게 할 때 쓰이는 도구이다. (실행파일이 실행되면 OCaml 의 프롬프트가 나온다.)

 

 

Posted by Scripter

댓글을 달아 주세요

MPIR 은 Multiple Precision Integers and Rationals 은 줄인 약자로서 C 언어나 C++ 언어로 매우 긴 자리의 수치 연산을 하는 프로그램을 작성할 때 사용되는 라이브러리이다.

참고. 위키피디아의 MPIR 설명

MPIR 은 GMP 처럼 무한 자리 수치 계산을 위한 (GMP 를 대체하는) 기본 라이브러리이다. MPIR 은 정수 계산, 유리수 계산, 부동소수점수 계산은 지원하지만, 복소수 계산은 지원하지 않는다.

MPIR 은 GMP 보다 훨씬 다양한 OS 를 지원하며 CPU 에 최적화 되어있다. MPIR 은 LGPL 3 적작권으로 보호받는 소스 공개 소프트웨어이다. 상업용 패키지에 포함시킬 때는 MPIR 이 GMP 보다 라이센스 면에서 더 자유로운 것 같다.

 

다음은 MPIR 홈페이지에서 소개하는 글의 일부이다.

----------------------------------------------------

About MPIR

MPIR is an open source multiprecision integer (bignum) library forked from the GMP (GNU Multi Precision) project. It consists of much code from past GMP releases, in combination with much original contributed code. A brief introduction can be found here Introduction(French)

MPIR is constructed by a developer and vendor friendly community of professional and amateur mathematicians, computer scientists and hobbyists.

The primary goals of the MPIR project are:

  • To have a developer friendly community.
  • To foster links with hardware and software vendors.
  • Development of parallel algorithms for multiprecision arithmetic including support for GPU's and other multicore processors.
  • To provide build support out-of-the-box for Linux, Apple, Sun and Microsoft Windows systems.
  • To overall license the project with the GNU LGPL license.
  • To maintain full interface support with GMP - MPIR is a drop-in replacement for GMP.
  • Support for building MPIR using Microsoft Visual Studio 2010 for use in both 32-bit and 64-bit versions of Windows.

----------------------------------------------------

MPIR 2.6.0 이 그 이전 버전과 다른 부분은 매우 많겠지만, 우선 눈에 보이는 두 가지만 언급한다면, 하나는 64비트 CPU 와 OS 를 확실하게 지원한다는 것이고, 다른 하나는 Visual Studio 2010 에 더 쉽게 설치된다는 것이다. (하지만 안정적인 면에서는 2.6.0 보다 그 이전 버전이 좋지 않나 생각한다.)

이 글에서는 32 비트 윈도우 XP 에 cygwin 용으로, MinGW 용으로, 그리고 Visual Studio 2010 용으로 각각 빌드하여 설치하고 테스트한 결과를 남겨 두고자 한다.

 

 

1. Visual Studio 2010 에 설치하기

단계 1.  압축을 푼다.

압축 해제돤 것을 모두 폴더 D:\mpir-2.6.0 에 둔 것으로 간주하고 다음 단계를 계속 진행한다.

Visual Studio 2010 용 솔루션 파일 mpir.sln 은 폴더 D:\mpir-2.6.0\build.vc10 에 존재해야 한다.

 

단계 2.  MPIR 2.6.0 설치 과정

Visual Studio 2010 의 메뉴에서 "파일(F)" -> "열기(O)" -> "프로젝트/솔루션(P).." 를 선택하여 파일 D:\mpir-2.6.0\build.vc10\mpir.sln 을 연다.

Visual Studio 2010 의 메뉴에서 "빌드(B)" -> "구성 관리자(O)..." 를 선택한다.

아래의 그림 처럼 세 가지 항목을 선택한다. (체크박스에 체크 확인)

 

 

메뉴에서 "빌드(B)" -> "솔루션 다시 빌드(S)" 를 선택하여 (위에서 처럼) 구성관리자에서 선택햇던 항목들을 모두 빌드한다.

 

단계 3.  빌드 후 확인

dll 파일과 관련 헤더 파일은 폴더 D:\mpir-2.6.0\build.vc10\dll\Win32\Releae 에 생성되고, lib 파일과 관련 헤더 파일은 폴더 D:\mpir-2.6.0\build.vc10\lib\Win32\Releae 에 생성된다.

만일 위의 구성관리자에서 체크된 세 가지 항목을 (Release 대신) Debug 로 선택하였다면, dll 파일과 관련 헤더 파일은 폴더 D:\mpir-2.6.0\build.vc10\dll\Win32\Debug 에 생성되고, lib 파일과 관련 헤더 파일은 폴더 D:\mpir-2.6.0\build.vc10\lib\Win32\Debug 에 생성된다.

Visual Studio 2010 용으로 빌드된 mpir 은 C++ 용 라이브러리 mpirxx.lib 가 추가로 더 생성되지만, dll 파일로는 mpir.dll 만 생성된다. (mpirxx.dll 파일은 별도로 생성되지 않는다.)

 

단계 4.  MPIR 2.6.0 설치 후 테스트

아래세 제시된 C 소스와 C++ 소스를 각각 컴파일하여 실행해본다. (컴파일 명령은 각 소스의 주석문 참조)

 

 

2. cygwin 에 설치하기

단계 1.  압축을 푼다.

 

단계 2.  MPIR 2.6.0 설치 순서

아래의 configure 명령 중에 옵션 --enable-cxx CXXFLAGS=-g 이 중요하다. 이 옵션이 없으면 mpir 의 C++ 용 헤더 파일과 라이브러리가 설치되지 않는다. (Visual Studio 2010 용으로 빌드하는 것 보다는 시간이 훨씬 더 오래 걸린디.)

$ ./configure --prefix=/usr --enable-cxx CXXFLAGS=-g
$ make
$ make check
$ make install
$ make clean

설치가 성공적으로 끝나면 헤더 파일은 /usr/include 폴더에  라이브러리 파일은 /usr/lib 폴더에 생성된다.

 

단계 3.  MPIR 2.6.0 설치 후 테스트

아래세 제시된 C 소스와 C++ 소스를 각각 컴파일하여 실행해본다. (컴파일 명령은 각 소스의 주석문 참조)

 

 

3. MinGW 에 설치하기

단계 1.  압축을 푼다.

 

단계 2.  MPIR 2.6.0 설치 순서

아래의 configure 명령 중에 옵션 --enable-cxx CXXFLAGS=-g 이 중요하다. 이 옵션이 없으면 mpir 의 C++ 용 헤더 파일과 라이브러리가 설치되지 않는다. (Visual Studio 2010 용으로 빌드하는 것 보다는 시간이 훨씬 더 오래 걸린디.)

$ ./configure --prefix=/c/MinGW --enable-cxx CXXFLAGS=-g
$ make
$ make check
$ make install
$ make clean

설치가 성공적으로 끝나면 헤더 파일은 /c/MinGW/include 폴더에  라이브러리 파일은 /c/MinGW/lib 폴더에 생성된다.

 

단계 3.  MPIR 2.6.0 설치 후 테스트

아래세 제시된 C 소스와 C++ 소스를 각각 컴파일하여 실행해본다. (컴파일 명령은 각 소스의 주석문 참조)

 

 

4. mpir 설치 후 테스트를 위한 C 소스와 C++ 소스

 

 //  Filename: testMPIR_01.c
//
//      This has been tested with MPIR 2.5.2.
//
//   Compile: gcc -o testMPIR_01 testMPIR_01.c -lmpir
//   Execute: ./testMPIR_01
//
//    Or
//
//   Compile: cl testMPIR_01.cpp mpir.lib
//   Execute: testMPIR_02
//
//   Date: 2013. 1. 16.
//   Copyright (c) PH Kim  ( pkim __AT__ scripts.pe.kr )

#include <stdio.h>
#include <mpir.h>

void foo (mpz_t result, const mpz_t param, int n)
{
    int i;

    mpz_mul_ui (result, param, n);
    gmp_printf ("Initialized r = %Zd\n", result);

    for (i = 1; i < n; i++) {
        mpz_add_ui (result, result, i*7);
        gmp_printf ("    r = %Zd  <--  r is added by %2d*7 = %3d\n", result, i, i*7);
    }
}


int main (void)
{
    mpz_t r, n;

    mpz_init (r);
    mpz_init_set_str (n, "123456", 0);

    mpz_set_si (r, 0);

    gmp_printf ("r = %Zd, n = %Zd\n", r, n);
    foo (r, n, 20L);
    gmp_printf ("Result is r = %Zd\n", r);

    mpz_clear(n);
    mpz_clear(r);

    return 0;
}

/*
Output:
r = 0, n = 123456
Initialized r = 2469120
    r = 2469127  <--  r is added by  1*7 =   7
    r = 2469141  <--  r is added by  2*7 =  14
    r = 2469162  <--  r is added by  3*7 =  21
    r = 2469190  <--  r is added by  4*7 =  28
    r = 2469225  <--  r is added by  5*7 =  35
    r = 2469267  <--  r is added by  6*7 =  42
    r = 2469316  <--  r is added by  7*7 =  49
    r = 2469372  <--  r is added by  8*7 =  56
    r = 2469435  <--  r is added by  9*7 =  63
    r = 2469505  <--  r is added by 10*7 =  70
    r = 2469582  <--  r is added by 11*7 =  77
    r = 2469666  <--  r is added by 12*7 =  84
    r = 2469757  <--  r is added by 13*7 =  91
    r = 2469855  <--  r is added by 14*7 =  98
    r = 2469960  <--  r is added by 15*7 = 105
    r = 2470072  <--  r is added by 16*7 = 112
    r = 2470191  <--  r is added by 17*7 = 119
    r = 2470317  <--  r is added by 18*7 = 126
    r = 2470450  <--  r is added by 19*7 = 133
Result is r = 2470450
*/

 

 

// Filename: testMPIR_02.cpp
//
//      This has been tested with MPIR 2.5.2.
//
//   Compile: g++ -o testMPIR_02 testMPIR_02.cpp -lmpirxx -lmpir
//   Execute: ./testMPIR_02
//
//    Or
//
//   Compile: cl /EHsc testMPIR_02.cpp mpir.lib mpirxx.lib
//   Execute: testMPIR_02
//
//   Date: 2013. 1. 16.
//   Copyright (c) PH Kim ( pkim __AT__ scripts.pe.kr )

// #include <stdio.h>
#include <iostream>
#include <mpirxx.h>
#include <mpir.h>

using namespace std;

int main (void)
{
    mpz_class a, b, c;

    a = 1234;
    b = "-5678";
    c = a + b;

    cout << "Given two numbers are " << a << " and " << b << "." << endl;
    cout << "  Their sum is " << c << "." << endl;
    cout << "  Its absolute value is |" << a <<  " + (" << b << ")| = " << abs(c) << "." << endl;
    cout << "  Their product is " << a << "*(" << b << ") = " << (a*b) << "." << endl;

    return 0;
}

/*
Output:
Given two numbers are 1234 and -5678.
  Their sum is -4444.
  Its absolute value is |1234 + (-5678)| = 4444.
  Their product is 1234*(-5678) = -7006652.
*/

 

 

'소개와 설치 > MPIR' 카테고리의 다른 글

윈도우에 MPIR 라이브러리 설치하고 사용하기  (2) 2013.01.16
Posted by Scripter
TAG gmp, MPIR

댓글을 달아 주세요

  1. 김성수 2013.09.30 18:37  댓글주소  수정/삭제  댓글쓰기

    안녕하세요 질문이 있는데 Visual Studio 2010에서 옵션설정까지 한 후 솔루션 빌드를 누르면


    다른 프로세스가 파일을 사용 중이기 때문에 프로세스가 액세스 할 수 없습니다. 와 함께 다른 오류들도 많이 뜨는데

    이런 경우는 어떻게 처리 해야 하는지 알려 주실 수 있나요??

  2. Scripter 2013.10.18 04:21 신고  댓글주소  수정/삭제  댓글쓰기

    디버깅 시작한 후 디버깅 종료를 안해서
    그런 것이 아닐까요?

음이 아닌 실수 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 )

 

Lua 언어에는 지수 연산을 하는 math.pow(밑수, 지수) 함수가 이미 구현되어 있다. 하지만 차후 필요한 데가 있을 것 같아서 이와 유사한 n 제곱 함수와 n 제곱근 함수를 구현해 보았다.

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

아래의 소스는 대부분 버전의 Lua 에서 실행되도록 작성된 소스이다.

#!/usr/bin/env lua

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

local MAX_ITER = 20000
local M_EPSILON = 1.0e-15

local BASE36 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"

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

    local arr = {} 
    local q, r = num, 0 
    while q >= radix do 
        r = math.fmod(q, radix) 
        q = math.floor(q / radix) 
        table.insert(arr, string.sub(BASE36, r+1, r+1)) 
    end

    table.insert(arr, string.sub(BASE36, q+1, q+1)) 
    if isNegative then 
        table.insert(arr, "-") 
    end 
    local ret = "" 
    for i = #arr, 1, -1 do 
        ret = ret .. arr[i] 
    end 
    return ret
end


--
-- Compute the n-th root of x to a given scale, x > 0.
--
function nPow(a, n)
    if n > 0 then
        if n == 1 then
            return a
        else
            if a == 0.0 or a == 1.0 then
                return a
            elseif a == -1.0 then
                if n % 2 == 1 then
                    return -1.0
                else
                    return 1.0
                end
            elseif a < 0.0 then
                if n % 2 == 1 then
                    return -nPow(-a, n)
                else
                    return nPow(-a, n)
                end
            else
                local y = 1.0
                for i = 1, n do
                    y = y * a
                end
                return y
            end
        end
    elseif n == 0 then
        return 1.0
    else      --  when n < 0
        if a == 0.0 then
            error('Negative powering exception of zero.')
        else
            if n == -1 then
                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 then
        if n == 1 then
            return a
        else
            if a == 0.0 or a == 1.0 then
                return a
            elseif a == -1.0 then
                if n % 2 == 1 then
                    return -1.0
                else
                    return 1.0
                end
            elseif a < 0.0 then
                if n % 2 == 1 then
                    return -gPow(-a, n)
                else
                    return gPow(-a, n)
                end
            else
                local y = 1.0
                local r = a
                local m = 8*4 - 1           --  8*sizeof(int) - 1;
                local one = 1
                local sn = itoa(n, 2)
                for i = 0, m-1 do
                    if string.sub(sn, string.len(sn) - i, string.len(sn) - i) == '0' then          
                        y = y * 1.0
                    else
                        y = y * r
                    end
                    r = r*r
                    one = one * 2
                    if one > n then
                        break
                    end
                end
                return y
            end
        end
    elseif n == 0 then
        return 1.0
    else      --  when n < 0
        if a == 0.0 then
            error('Negative powering exception of zero.')
        else
            if n == -1 then
                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 then
        if n == 1 then
            return a
        else
            if a == 0.0 or a == 1.0 then
                return a
            elseif a == -1.0 then
                if n % 2 == 1 then
                    return -1.0
                else
                    return 1.0
                end
            elseif a < 0.0 then
                if n % 2 == 1 then
                    return -mPow(-a, n)
                else
                    return mPow(-a, n)
                end
            else
                y = 1.0
                r = a
                m = n
                while m > 0 do
                    if (m % 2) == 1 then
                        y = y * r
                    end
                    r = r*r
                    m = math.floor(m / 2)
                end
                return y
            end
        end
    elseif n == 0 then
        return 1.0
    else      --  when n < 0
        if a == 0.0 then
            error('Negative powering exception of zero.')
        else
            if n == -1 then
                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 then
        error('Cannot find the sqrt of a negative number.')
    elseif a == 0.0 or a == 1.0 then
        return a
    else
        local x1 = a
        local x2 = (x1 + a/x1)/2.0
        local er = x1 - x2
        local counter = 0
        while x1 + er ~= x1 do
            x1 = x2
            x2 = (x1 + a/x1)/2.0
            er = x1 - x2
            if math.abs(er) < math.abs(M_EPSILON*x1) then
                break
            end
            counter = counter + 1
            if counter > MAX_ITER then
                break
            end
        end
        if counter >= MAX_ITER then
            error('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 or a == 1.0 or a == -1.0 then
        return a
    elseif a < 0.0 then
        return -newtonCbrt(-a)
    else
        local x1 = a
        local x2 = (2.0*x1 + a/(x1*x1))/3.0
        local er = x1 - x2
        local counter = 0
        while x1 + er ~= x1 do
            x1 = x2
            x2 = (2.0*x1 + a/(x1*x1))/3.0
            er = x1 - x2
            if math.abs(er) < math.abs(M_EPSILON*x1) then
                break
            end
            counter = counter + 1
            if counter > MAX_ITER then
                break
            end
        end
        if counter >= MAX_ITER then
            error('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 then
        return 1.0
    elseif n == 1 then
        return a
    elseif n > 0 then
        if a == 0.0 or a == 1.0 then
            return a
        elseif a == -1.0 then
            if n % 2 == 1 then
                return a
            else
                error('Cannot find the even n-th root of a negative number.')
            end
        elseif a < 0.0 then
            if n % 2 == 1 then
                return -newtonNthRoot(n, -a)
            else
                error('Cannot find the even n-th root of a negative number.')
            end
        elseif a < 1.0 then
            return 1.0/newtonNthRoot(n, 1.0/a)
        else
            local x1 = a
            local xn = mPow(x1, n - 1)
            local x2 = ((n - 1)*x1 + a/xn)/n
            local er = x1 - x2
            local counter = 0
            while x1 + er ~= x1 do
                x1 = x2
                xn = mPow(x1, n - 1)
                x2 = ((n - 1)*x1 + a/xn)/n
                er = x1 - x2
                if math.abs(er) < math.abs(M_EPSILON*x1) then
                    break
                end
                counter = counter + 1
                if counter > MAX_ITER then
                    break
                end
            end
            if counter >= MAX_ITER then
                error('Inaccurate n-th root exception by too many iterations.')
            end
            return x2
        end
    else
        if a == 0.0 then
            error('Cannot find the negative n-th root of zero.')
        else
            return 1.0/newtonNthRoot(-n, a)
        end
    end
end

 

local x = 16.0
local u = math.sqrt(x)


print("[ Testing heronSqrt(double) ]--------------------")
print(string.format("x = %g", x))
print(string.format("u = sqrt(%g) = %g", x, u))
y = heronSqrt(x)
print(string.format("y = heronSqrt(%g) = %g", x, y))
print(string.format("y*y = %g", y*y))
print()

print("[ Testing newtonCbrt(double) ]--------------------")
x = -216.0
print(string.format("x = %g", x))
print(string.format("-exp(log(-x)/3.0) = %g", -math.exp(math.log(-x)/3.0)))
local w = newtonCbrt(x)
print(string.format("w = newtonCbrt(%g) = %g", x, w))
print(string.format("w*w*w = %g", w*w*w))
print()

x = 729000000000.0
print(string.format("x = %g", x))
print(string.format("exp(log(x)/3.0) = %g",  math.exp(math.log(x)/3.0)))
w = newtonCbrt(x)
print(string.format("w = newtonCbrt(%g) = %g", x, w))
print(string.format("w*w*w = %g", w*w*w))
print()

print("[ Testing newtonNthRoot(int, double) ]--------------------")
z = newtonNthRoot(3, x)
print(string.format("x = %g", x))
print(string.format("z = newtonNthRoot(3, %g) = %g", x, z))
print(string.format("z*z*z = %g", z*z*z))
print()

x = 12960000000000000000.0
local z = newtonNthRoot(4, x)
print(string.format("x = %g", x))
print(string.format("z = newtonNthRoot(4, x) = newtonNthRoot(4, %g) =  %g", x, z))
print(string.format("z*z*z*z = %g",  z*z*z*z))
print()

x = 1.0/12960000000000000000.0
z = newtonNthRoot(4, x)
print(string.format("x = %g", x))
print(string.format("exp(log(x)/4.0) = %g", math.exp(math.log(x)/4.0)))
print(string.format("z = newtonNthRoot(4, x) = newtonNthRoot(4, %g) =  %g", x, z))
print(string.format("z*z*z*z = %g",  z*z*z*z))
print()


x = -4.0
print("[ Test Exception heronSqrt(double) ]--------------------")
print(string.format("x = %g", x))
print(string.format("Calculating heronSqrt(%g)", x))
local y  -- = heronSqrt(x)
status, value = pcall(heronSqrt, x)
if status then
    y = value
    print(string.format("y = heronSqrt(%g) = %g", x, y))
    print(string.format("y*y = %g", y*y))
    print()
else
    print(string.format("%s\nCaught some exception in calculating heronSqrt(%g)", value, x))
    print()
end

x = -4.0
print("[ Test Exception in newtonCbrt(double) ]--------------------")
print(string.format("x = %g", x))
print(string.format("Calculating newtonCbrt(%g)", x))
status, value = pcall(newtonCbrt, x)
if status then
    y = value
    print(string.format("y = newtonCbrt(%g) = %g", x, y))
    print(string.format("y*y*y = %g", y*y*y))
    print()
else
    print(string.format("%s\nCaught some exception in calculating newtonCbrtrt(%g)", value, x))
    print()
end


print("[ Test calculations by powering ]-----------------------------")
x = 200.0
z = newtonNthRoot(10, x)
print(string.format("x = %g", x))
print(string.format("exp(log(x)/10.0) = %g", math.exp(math.log(x)/10.0)))
print(string.format("z = newtonNthRoot(10, x) = newtonNthRoot(10, %g) = %g", x, z))
print(string.format("pow(z, 10) = %g", math.pow(z, 10)))
print()

x = 3001.0
z = newtonNthRoot(99, x)
print(string.format("x = %g", x))
print(string.format("exp(log(x)/99.0) = %g", math.exp(math.log(x)/99.0)))
print(string.format("z = newtonNthRoot(99, x) = newtonNthRoot(99, %g) = %g", x, z))
print(string.format("pow(z, 99) = %g", math.pow(z, 99)))
print()

x = 3001.0
z = newtonNthRoot(-99, x)
print(string.format("x = %g", x))
print(string.format("exp(log(x)/-99.0) = %g", math.exp(math.log(x)/-99.0)))
print(string.format("z = newtonNthRoot(-99, x) = newtonNthRoot(-99, %g) = %g", x, z))
print(string.format("1.0/pow(z, 99) = %g", 1.0/math.pow(z, 99)))
print()


print(string.format("pow(2.1, 2.1) = %g", math.pow(2.1, 2.1)))
print(string.format("pow(2.1, -2.1) = %g", math.pow(2.1, -2.1)))
print(string.format("pow(2.1, 2.1) * pow(2.1, -2.1) = %g", math.pow(2.1, 2.1)*math.pow(2.1,  -2.1)))
print(string.format("2.1**2.1 = exp(2.1*log(2.1)) = %g", math.exp(2.1*math.log(2.1))))
print(string.format("2.1**(-2.1) = exp(-2.1*log(2.1)) = %g", math.exp(-2.1*math.log(2.1))))
print(string.format("2.1**2.1 * 2.1**(-2.1) = exp(2.1*log(2.1)) * exp(-2.1*log(2.1)) = %g", math.exp(2.1*math.log(2.1)) * math.exp(-2.1*math.log(2.1))))
print()


k = 301
x = -1.029
t1 = nPow(x, k)
t2 = gPow(x, k)
t3 = mPow(x, k)
print(string.format("math.pow(%g, %d) = %g", x, k,  math.pow(x, k)))   -- pow(x, k)
print(string.format("t1 = nPow(%g, %d) = %g", x, k,  t1))
print(string.format("t2 = gPow(%g, %d) = %g",x, k,  t2))
print(string.format("t3 = mPow(%g, %d) = %g", x, k,  t3))
print(string.format("t1 / t2 = %g", t1 / t2))
print(string.format("t1 - t2 = %g", t1 - t2))
io.write("t1 == t2 ? ")
if t1 == t2 then
    print "yes"
else
   print "no"
end
print(string.format("t1 / t3 = %g", t1 / t3))
print(string.format("t1 - t3 = %g", t1 - t3))
io.write("t1 == t3 ? ")
if t1 == t3 then
    print "yes"
else
   print "no"
end
print(string.format("t2 / t3 = %g", t2 / t3))
print(string.format("t2 - t3 = %g", t2 - t3))
io.write("t2 == t3 ? ")
if t2 == t3 then
    print "yes"
else
   print "no"
end
print()

print "Done."


--[[
# System.out.println("sizeof(double) = " + sizeof(double) );;
# System.out.println("sizeof(int) = " + sizeof(int) );
## print "sizeof(double) = %s = %d" % ("%X" % -1.0, len("%X" % -1.0))
## print "sizeof(int) = %s = %d" % ("%X" % -1, len("%X" % -1))
# print "sizeof(double)*4 = " + String.format("%X", Double.doubleToRawLongBits(-1.0)).length()*4 );;
# print sizeof(int)*4 = " + String.format("%X", -1).length()*4 );
# print sys.getsizeof(int)   # See: http://stackoverflow.com/questions/449560/how-do-i-determine-the-size-of-an-object-in-python
# print sys.getsizeof(-1.0)   # See: http://stackoverflow.com/questions/449560/how-do-i-determine-the-size-of-an-object-in-python
# print sys.getsizeof(-1.0)*4   # See: http://stackoverflow.com/questions/449560/how-do-i-determine-the-size-of-an-object-in-python
# print sys.getsizeof(-1.0)*4   # See: http://stackoverflow.com/questions/449560/how-do-i-determine-the-size-of-an-object-in-python
## print getsizeof(-1.0)*4   # See: http://stackoverflow.com/questions/449560/how-do-i-determine-the-size-of-an-object-in-python
--]]


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

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

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

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

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

x = 7.71605e-020
exp(log(x)/4.0) = 1.66667e-005
z = newtonNthRoot(4, x) = newtonNthRoot(4, 7.71605e-020) =  1.66667e-005
z*z*z*z = 7.71605e-020

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

[ Test Exception in 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) = 1.69865
z = newtonNthRoot(10, x) = newtonNthRoot(10, 200) = 1.69865
pow(z, 10) = 200

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

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

pow(2.1, 2.1) = 4.74964
pow(2.1, -2.1) = 0.210542
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

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-011
t1 == t2 ? no
t1 / t3 = 1
t1 - t3 = 6.18456e-011
t1 == t3 ? no
t2 / t3 = 1
t2 - t3 = 0
t2 == t3 ? yes

Done.
--]]

 

 

 

Posted by Scripter

댓글을 달아 주세요

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

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

수학에서 sin 함수의 역함수는 arcsin 으로 표기되는데, ErLang 언어에서는 asin 함수로 구현되어 있다.

OCaml 언어는 F#, Scala 언어 처럼 비순수 함수형 언어이다. (여기서 바순수라 함은 절차적 언어 처럼 for, while, break 등의 제어문 기능을 갖고 있어서 C 언어나 Java 언어 처럼 작성할 수 있다는 뜻이다.)

OCaml 언어로 작성된 소스에서는 각 명령 줄이 두 개의 세미콜론(;;)으로 끝나야 한다.

영문 위키피디아의 OCaml  프로그래밍 언어 설명: http://en.wikipedia.org/wiki/OCaml

OCaml 언어로 부동소수점수(float 타입, 이느 C 언어와 Java 언어의 double 타입에 해당)의 사칙 연산 기로가 +, -, *, / 가 아니라 각 연산지 뒤에 점(.)을 하나씩 추가한 +., -., *., /. 임에 주위 한다. 정수(int) 타입의 사칙 연산 기호는 +, -, *, / 를 그대로 사용한다. 그리고 float 타입과 int 타입을 섞어서 연산할 때는 반드시 타입을 통일시키는 작업을 해야 한다.

아래에서 샤프 기호(#)는 OCaml 의 프롬프트이다. 테스트는 진한 글자로 된 부분만 입력하면 된다.

명령프롬프트> ocaml
        Objective Caml version 3.12.1

# 3 + 1.2;;
Characters 4-7:
  3 + 1.2;;
      ^^^
Error: This expression has type float but an expression was expected of type
         int
# (float_of_int 3) + 1.2;;
Characters 0-16:
  (float_of_int 3) + 1.2;;
  ^^^^^^^^^^^^^^^^
Error: This expression has type float but an expression was expected of type
         int
# (float_of_int 3) +. 1.2;;
- : float = 4.2
# 3 + (int_of_float 1.2);;
- : int = 4

 

아래의 소스는 컴파일 없이 "ocaml 소스파일명" 으로 실행해도 되고, "ocamlc -o 실행파일명 소스파일명" 컴파일한 뒤 생성된 실행파일을 실행해도 된다.

컴파일하여 실행하는 경우 현재 최신 버전인 OCaml 4.00.1 은 "NTVDM CPU CS ......" 에러가 발생힌디.


OCaml 3.12.* 에서는 컴파일 하여 실행하더러도 아무 문제가 없다.

(윈도우 Vista, XP, 7 등에서 OCaml 3.12.1 은 설치되는 중에 시스템 환경변수 PATH 의 값을 삭제해 버리므로 주의를 요한다. PATH 의 값을 다른 곳에 저장해 두었다가 복원해야 함.)

 

(*
   Filename: testArcSine.ml
 
   Execute: ocaml testArcSine.ml

     Or
 
   Compile: ocamlc -o testArcSine testArcSine.ml
   Execute: ./testArcSine
 
     Or
 
   Compile: ocamlc -o testArcSine.exe testArcSine.ml
   Execute: testArcSine.exe
 
   Date: 2013. 1. 3.
   Copyright (c) pkim _AT_ scripts.pe.kr
*)


let asinh x = log(x +. sqrt(x *. x +. 1.0));;

let acosh x = log(x +. sqrt(x *. x -. 1.0));;

let x = -0.9;;
let y = asin(x);;

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

let x = 1.1;;
let u = acosh(x);;
let _ = Printf.printf "u = acosh(%g) = %.10f\n" x u;;
let v = asinh(x);;
let _ = Printf.printf "v = asinh(%g) = %.10f\n" x v;;

let _ = Printf.printf "cosh(u) = cosh(%.10f) = %g\n" u (cosh u);;
let _ = Printf.printf "sinh(v) = sinh(%.10f) = %g\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

댓글을 달아 주세요

Jython은 JVM(자바 가상 기계, Java Virtual Machine) 상에서 동작하는 파이썬 인터프리터이다. 한 때는 JPython이라는 이름으로 불리우기도 했는데, 지금은 더 짧은 이름 Jython으로 통한다.

리녹스 시스템에 슈퍼유저(su) 권한으로 Jython을 러치하면 캐쉬 디렉토리의 설정 문제로 약간은 다소 귀찮은 일이 발샐한다. 여기서는 이런 문제도 해결하고 Tomcat과 연동하여 PyServlet을 동자기켜 보기로 한다.


* Jython 2.5.3 다운로드

Jython의 현재 최신 릴리즈는 2.5.3이다 Jython 홈페이지 http://jythom.org 에서 jython-installer-2.5.3 을 다운받는다. 다운받은 파일을 적당한 곳으로 옮기고, 터미널에서 그 폴더로 체인지 디렉토리(cd)하여 다음 java 명령으로 jython을 설치한다.

$ sudo java -jar jython-installer-2.5.3.jar






이 글에서는 Jython을 /usr/local/jython-2.5.3에 서리한 것으로 간주하고 계속 진행한다.

/etc/profile에 환경변수 JYTHON_HOME과 PATH를 잡아준다. (다음 두 줄 추가)

$ sudo vi /etc/profile

JYTHON_HOME=/usr/local/jthon-2.5.3; export JYTHON_HOME

PATH=$JYTHON_HOME/bin"$PATH; export PATH


변경된 환경변수 JYTHON_HOME과 PATH를 현재의 셀에 적용시킨다.

$ source /etc/profile



* jython 인터프리터 실행

jython 명령을 사용하면 캐쉬 디렉토리 관련 에러가 뜨면서 실행은 된다.


$ jython hello.py
*sys-package-mgr*: can't create package cache dir, '/usr/local/jython-2.5.3/cachedir/packages'
Hello, world!

이제 이 문제를 해결해 보자. 해결하는데 두 가지 방법이 있다. 하나는 jython 명령을 내릴 때 -D 옵션을 쓰는 것이도, 다른 하나는 ~/.jython 파일에서 캐쉬 디렉토리를 잡아주는 방법이다.

(참고. 전체 경로에 ~ 나 $HOME 은 적어봐야 jython이 인식하지 못한다.)

$ jython -Dpython.cachedir=전체경로 hello.py
Hello, world!


다음 한 줄로 된 파일 ~/.jython 을 작성한다.

$ vi ~/.jython

python.cachedir=전체경로


$ jython hello.py
Hello, world!



PyServlet 설정 및 실행

* web.xml 파일에 추가될 내용

    <servlet>
        <servlet-name>PyServlet</servlet-name>
        <servlet-class>org.python.util.PyServlet</servlet-class>
        <init-param>
         <param-name>python/home</param-name>
         <param-value>/opt/usr/local/jython-2.5.3</param-value>
        </init-param>
    </servlet>

    <servlet-mapping>
        <servlet-name>PyServlet</servlet-name>
        <url-pattern>*.py</url-pattern>
    </servlet-mapping>



* 수정 전 PyServlet: enter.py

import javax.servlet.http as http

class enter(http.HttpServlet):
  def doPost(self, request, response):
    session = request.getSession(1)
    counter = session.getAttribute("counter")
    try:
        counter = int(counter)
    except: # counter is None
        counter = 0
    counter += 1
    session.setAttribute("counter", counter)
    response.contentType = "text/html; charset=utf-8"
    out = response.outputStream print >> out, """The string you entered is: %s. <br />
You have played this game %s times.\n<hr>""" % (
request.getParameter("thing"), counter)
    self.doGet(request, response)

  def doGet(self, request, response):
    response.contentType = "text/html; charset=utf-8"
    out = response.outputStream print >> out, """Enter a string: <form method="post">
<input type="text" name="thing">
<input type="submit">
</form>"""



* Ubuntu에서 Tomcat 6 & Jython 2.5.3을 사용하여 수정전 enter.py를 실행한 장면




* 수정 후 PyServlet: enter.py (utf-8 한글 파라미터 처리를 위해 파란색 부분만 수정됨)

# -*- encoding: utf-8 -*-

import javax.servlet.http as http

class enter(http.HttpServlet):

  def doPost(self, request, response):
    session = request.getSession(1)
    counter = session.getAttribute("counter")
    try:
        counter = int(counter)
    except: # counter is None
        counter = 0
    counter += 1
    session.setAttribute("counter", counter)
    request.setCharacterEncoding("utf-8")
    response.contentType = "text/html; charset=utf-8"
    out = response.outputStream
    print >> out, """The string you entered is: %s. <br />
You have played this game %s times.\n<hr>""" % (
request.getParameter("thing").encode("utf-8"), counter)
    self.doGet(request, response)

  def doGet(self, request, response):
    response.contentType = "text/html; charset=utf-8"
    out = response.outputStream
    print >> out, """Enter a string: <form method="post">
<input type="text" name="thing">
<input type="submit">
</form>"""


* Ubuntu에서 Tomcat 6 & Jython 2.5.3을 사용하여 수정된 enter.py를 실행한 장면







Posted by Scripter

댓글을 달아 주세요