Small BASIC은 Microsoft에서 제작 배포하는 BASIC 언어 인터프리터로서

편집기가 내장되어 있으며, 그래픽 기능도 있으며,  Dot NET 4.5 환경에서 동작합니다.

Small BASIC 홈페이지에서 다운로드하여 설치할 수 있으며, 풍부한 튜토리얼도 있습니다.

 

Small BASIC을 설치하고, 처음 실행한 화면입니다.

 

다음의 딱 한줄 을 편집기에 쓰고

TextWindow.WriteLine("Hello World!")

파일 저장하고(파일 확장자가 sb로 저장됨),  실행 버튼 누르면 

Hello World! 가 출력된 컨솔창이 뜹니다.

아래의 몇 줄을 입력하고

Turtle.Show()
For i = 1 To 45
  Turtle.Turn(8)
  Turtle.Move(10)
EndFor

저장 버튼 누르고, 실행 버튼 누르면 아래 처럼 그래픽이 그려집니다.

 

 

Posted by Scripter
,

지난 2021년 12월 6일에 Python 3.10.1 이 출시되었다.

 

설치하자 마자 인터프리터 쉘로 간단히 테스트해 보았다.

 

Python 3.10.1 (tags/v3.10.1:2cd268a, Dec  6 2021, 19:10:37) [MSC v.1929 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> print("Hello~")
Hello~
>>> for i in range(11):
...     print(2**i)
...
1
2
4
8
16
32
64
128
256
512
1024
>>> import math
>>> math.factorial(10)
3628800
>>> math.gamma(11)
3628800.0
>>> math.lgamma(11)
15.104412573075514
>>> math.log(math.gamma(11))
15.104412573075516
>>> math.exp(10)
22026.465794806718
>>> 10**10
10000000000
>>> 10.0**10.0
10000000000.0
>>> math.pow(10.0, 10.0)
10000000000.0
>>> math.exp(10.0*math.log(10.0))
10000000000.00004
>>> math.sqrt(10)
3.1622776601683795
>>> math.cbrt(10)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: module 'math' has no attribute 'cbrt'
>>> math.tan(1)
1.5574077246549023
>>> math.atan(1)
0.7853981633974483
>>> 4*(math.atan(1.0/5)*4 - math.atan(1.0/239))
3.1415926535897936
>>> math.pi
3.141592653589793
>>> math.e
2.718281828459045
>>> math.exp(1)
2.718281828459045
>>> (math.exp(1) - math.exp(-1))/2
1.1752011936438014             ^
SyntaxError: unmatched ')'
>>> math.sinh(1)
1.1752011936438014
>>> math.atan(1)
0.7853981633974483
>>> math.gcd(625, 1000)
125
>>> quit()

 

아직 세제곱근(cube root) 구하는 math.cbrt(float) 함수는 구현되지 않았다.

 

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

Union 타입 생성  연산자 '|' 기 Python 3.10.x 에 추가되었다.


>>> # Union 타입을 매개변수로 방아 Union 타입을 리턴허눈 험수
>>> # def f(list: list[Union[int, str]], param: Optional[int]) -> Union[float, str]

>>>  # 대신, 다음 구문으로 가능

>>> def f(list: list[int | str], param: int | None) -> float | str:
.>>> ..     pass
...


>> int 타입과 list[int] 타입의 Union 타입

>>> str(int | list[str])
'int | list[str]'



>>> 두 int 타입의 Union 타입
>>> str(int | int)
"<class 'int'>"


>>> Union 타입을 이용헌 인스턴스 확인

>>> isinstance("", int | str)
True


>>> Union 타입을 이용헌 상속 확인

>>> issubclass(bool, int | float)
True

 

>>> # 클래스 상속과 Union 타입 생성 연산자 확인
>>> class M(type):
...         def __or__(self, other): return "Hello"
...
>>> class C(metaclass=M): pass
...

>>> C | int
'Hello'


>>> int | C
int | __main__.C

 

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

다음은 아직은 아니지만 다음 릴리즈에 추가될 것 중의 하나이다.

우선 다음 내용을 test,py 라는 파일명으로 자장하고,

x = {'a':{'b':{'c':None}}}
x['a']['b']['c']['d'] = 1

 

프롬프트> python test,py

명령으로 실행합니다. 그러면 다음 에러 메시지가 나온다.

Traceback (most recent call last):
  File "test.py", line 2, in <module>
    x['a']['b']['c']['d'] = 1
TypeError: 'NoneType' object does not support item assignment

 

이 에러 메시지 만으로는 시퀀스 타입 자료에 어느 것이 None 인지 알 수가 없다.

다음 릴리즈에서는 에러 메시지가

Traceback (most recent call last):
  File "test.py", line 2, in <module>
    x['a']['b']['c']['d'] = 1
    ~~~~~~~~~~~^^^^^
TypeError: 'NoneType' object is not subscriptable

로 출력된다. (이는 핸재 Python Pre-Release 3.11.0a3 에서 확인되옸다.)

 

 

 

 

 

 

Posted by Scripter
,

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

 

 

 

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

Python 3.10.1 릴리즈 출시  (0) 2021.12.17
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

 

 

 

 

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)

 

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.c -I. mpir.lib
//   Execute: testMPIR_01
//
//   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 -I. 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.
*/

 

 

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 )

 

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
,