Java 에는 부호 없는 native 정수 타입이 없다.

Java 8에 와서야 부호 없는 정수를 처리하기 위한 메서드 몇 개가 추가되었다.

예를 들어, String을 native 타입 number로 변환하는 스태틱 메서드

        Long.parseUnsignedLong(String),  Integer.parseUnsignedint(String),

       Short.parseUnsignedShort(String),  Byte.parseUnsignedByte(String),

들과 역으로 native 타입 number를 String으로 변환하는 스태틱 메서드

        Long.toUnsignedString(long),  Integer.toUnsignedString(int)

가 있는데 이들은 타입 캐스팅할 댸 주의해야 할 부분이 있다.

아래의 Java 소스는 overflow 와 관련하여 심각한 문제가 발생할 수

있음을 보여 준다.

 

 

//  Filename: About_Java_Native_Number.java
//
//       Re-consider Java's native numbers (int or long or double) near to theirs maximal valuea
//
//
//  Compile: javac -d . About_Java_Native_Number.java
//  Execute: java About_Java_Native_Number
//
//
// Date: 2023.10.22


public class About_Java_Native_Number
{

    public static void main(String[] args)
    { 
        System.out.printf("What is pow(2, 30) = 2**30 (using Python's integer power operator expression)\n");
        System.out.printf("                   = 1 << 30 (using intege's shift opertor expression)\n");
        System.out.printf("                   = 2^30 (in LaTeX' math expression)\n");
        System.out.printf("\n");

        System.out.printf("Math.pow(2, 30) == %s\n", Math.pow(2, 30));
        System.out.printf("Math.pow(2, 30) == %e\n", Math.pow(2, 30));
        System.out.printf("Math.pow(2, 30) == %.9e\n", Math.pow(2, 30));
        System.out.printf("Math.pow(2, 30) == %g\n", Math.pow(2, 30));
        System.out.printf("Math.pow(2, 30) == %.0g\n", Math.pow(2, 30));
        System.out.printf("Math.pow(2, 30) == %.9g\n", Math.pow(2, 30));
        System.out.printf("Math.pow(2, 30) == %f\n", Math.pow(2, 30));
        System.out.printf("Math.pow(2, 30) == %.0f\n", Math.pow(2, 30));
        System.out.printf("Math.pow(2, 30) == %a\n", Math.pow(2, 30));
        System.out.printf("\n");

        System.out.printf("1 << 30 = %d\n", 1 << 30);
        System.out.printf("(1 << 30) + (1 << 30) = %d\n", (1 << 30) + (1 << 30) );
        System.out.printf("(1 << 30)*2 = %d\n", (1 << 30)*2);
        System.out.printf("1 << (1 << 30) << 1 = %d\n", (1 << 30) << 1 );
        System.out.printf("0x7FFFFFFF = %d\n", 0x7FFFFFFF);
        System.out.printf("0x7FFFFFFF + 1 = %d\n", 0x7FFFFFFF + 1);
        System.out.printf("0x7FFFFFFF + 2 = %d\n", 0x7FFFFFFF + 2);
        System.out.printf("0x7FFFFFFF + 2 = %d\n", 0x7FFFFFFF + 2);
        System.out.printf("0x7FFFFFFF + 1 - 1 = %d\n", 0x7FFFFFFF + 1 - 1);
        System.out.printf("0x7FFFFFFF + 2 - 2 = %d\n", 0x7FFFFFFF + 2 - 2);
        System.out.printf("0x7FFFFFFF + 3 - 3 = %d\n", 0x7FFFFFFF + 3 - 3);
        System.out.printf("\n");

        System.out.printf("Is it true that (0x7FFFFFFF + 1) - 1 = (%d + 1) - 1 = %d - 1 = %d ?\n", 0x7FFFFFFF, 0x7FFFFFFF + 1, (0x7FFFFFFF + 1) - 1);
        System.out.printf("Is it true that (0x7FFFFFFF + 2) - 2 = (%d + 2) - 2 = %d - 2 = %d ?\n", 0x7FFFFFFF, 0x7FFFFFFF + 2, (0x7FFFFFFF + 1) - 2);
        System.out.printf("Is it true that (0x7FFFFFFF + 3) - 3 = (%d + 3) - 3 = %d - 3 = %d ?\n", 0x7FFFFFFF, 0x7FFFFFFF + 3, (0x7FFFFFFF + 1) - 3);
        System.out.printf("\n");

        System.out.printf("It is true that 1 << 30 = %d\n", 1 << 30);
        System.out.printf("But, is it true that (1 << 30)*2/2 = (%d)*2/2 = %d/2 = %d ?\n", 1 << 30, (1 << 30)*2,  (1 << 30)*2/2);
        System.out.printf("And, is it true that (1 << 30)*2/4 = (%d)*2/4 = %d/4 = %d ?\n", 1 << 30, (1 << 30)*2,  (1 << 30)*2/4);
        System.out.printf("And, is it true that (1 << 30)*2/8 = (%d)*2/8 = %d/8 = %d ?\n", 1 << 30, (1 << 30)*2,  (1 << 30)*2/8);
        System.out.printf("\n");

        System.out.printf("Also, is it true that (1 << 30)*4/2 = (%d)*4/2 = %d/2 = %d ?\n", 1 << 30, (1 << 30)*4,  (1 << 30)*4/2);
        System.out.printf("Also, is it true that ((1 << 30)*4 + 1234567)/2 = ((%d)*4 + 1234567)/2 = (%d + 1234567)/2 = %d ?\n", 1 << 30, (1 << 30)*4,  ((1 << 30)*4 + 1234567)/2);
        System.out.printf("Then, is it true that (Math.pow(2, 30)*4 + 1234567)/2 = ((%.0f)*4 + 1234567)/2 = (%.0f + 1234567)/2 = %.0f ?\n", Math.pow(2, 30), Math.pow(2, 30)*4,  (Math.pow(2, 30)*4 + 1234567)/2);


        System.out.printf("In is known that Math.pow(2, 30) == (1 << 30) ? %s\n", Math.pow(2, 30) == (1 << 30));
        System.out.printf("\n");

        System.out.printf("Long.toUnsignedString((byte)0xFFL) = %s\n", Long.toUnsignedString((byte)0xFFL));
        System.out.printf("Long.toUnsignedString(0xFFL) = %s\n", Long.toUnsignedString(0xFFL));
        System.out.printf("Integer.toUnsignedString((byte)0xFFL) = %s\n", Integer.toUnsignedString((byte)0xFFL));
        System.out.printf("Integer.toUnsignedString(0xFF) = %s\n", Integer.toUnsignedString(0xFF));
        System.out.printf("Integer.toUnsignedString(0xFFFFFFFFFF) = %s\n", Integer.toUnsignedString(0xFFFFFFFF));
        System.out.printf("Long.toUnsignedString(0xFFFFFFFFFF) = %s\n", Long.toUnsignedString(0xFFFFFFFF));
        System.out.printf("Long.toUnsignedString(0x100000000L) = %s\n", Long.toUnsignedString(0x100000000L));
        System.out.printf("Long.toUnsignedString(0xFFFFFFFFFFFFFFFFL) = %s\n", Long.toUnsignedString(0xFFFFFFFFFFFFFFFFL));
        System.out.printf("Long.toUnsignedString(0x8000000000000000L) = %s\n", Long.toUnsignedString(0x8000000000000000L));
        System.out.printf("Long.toString(0xFFFFFFFFFFFFFFFFL) = %s\n", Long.toString(0xFFFFFFFFFFFFFFFFL));
        System.out.printf("Long.toString(0x8000000000000000L) = %s\n", Long.toString(0x8000000000000000L));
        System.out.printf("\n");

    }
}

/*
---------
 Output:
---------

What is pow(2, 30) = 2**30 (using Python's integer power operator expression)
                   = 1 << 30 (using intege's shift opertor expression)
                   = 2^30 (in LaTeX' math expression)

Math.pow(2, 30) == 1.073741824E9
Math.pow(2, 30) == 1.073742e+09
Math.pow(2, 30) == 1.073741824e+09
Math.pow(2, 30) == 1.07374e+09
Math.pow(2, 30) == 1e+09
Math.pow(2, 30) == 1.07374182e+09
Math.pow(2, 30) == 1073741824.000000
Math.pow(2, 30) == 1073741824
Math.pow(2, 30) == 0x1.0p30

1 << 30 = 1073741824
(1 << 30) + (1 << 30) = -2147483648
(1 << 30)*2 = -2147483648
1 << (1 << 30) << 1 = -2147483648
0x7FFFFFFF = 2147483647
0x7FFFFFFF + 1 = -2147483648
0x7FFFFFFF + 2 = -2147483647
0x7FFFFFFF + 2 = -2147483647
0x7FFFFFFF + 1 - 1 = 2147483647
0x7FFFFFFF + 2 - 2 = 2147483647
0x7FFFFFFF + 3 - 3 = 2147483647

Is it true that (0x7FFFFFFF + 1) - 1 = (2147483647 + 1) - 1 = -2147483648 - 1 = 2147483647 ?
Is it true that (0x7FFFFFFF + 2) - 2 = (2147483647 + 2) - 2 = -2147483647 - 2 = 2147483646 ?
Is it true that (0x7FFFFFFF + 3) - 3 = (2147483647 + 3) - 3 = -2147483646 - 3 = 2147483645 ?

It is true that 1 << 30 = 1073741824
But, is it true that (1 << 30)*2/2 = (1073741824)*2/2 = -2147483648/2 = -1073741824 ?
And, is it true that (1 << 30)*2/4 = (1073741824)*2/4 = -2147483648/4 = -536870912 ?
And, is it true that (1 << 30)*2/8 = (1073741824)*2/8 = -2147483648/8 = -268435456 ?

Also, is it true that (1 << 30)*4/2 = (1073741824)*4/2 = 0/2 = 0 ?
Also, is it true that ((1 << 30)*4 + 1234567)/2 = ((1073741824)*4 + 1234567)/2 = (0 + 1234567)/2 = 617283 ?
Then, is it true that (Math.pow(2, 30)*4 + 1234567)/2 = ((1073741824)*4 + 1234567)/2 = (4294967296 + 1234567)/2 = 2148100932 ?
In is known that Math.pow(2, 30) == (1 << 30) ? true

Long.toUnsignedString((byte)0xFFL) = 18446744073709551615
Long.toUnsignedString(0xFFL) = 255
Integer.toUnsignedString((byte)0xFFL) = 4294967295
Integer.toUnsignedString(0xFF) = 255
Integer.toUnsignedString(0xFFFFFFFFFF) = 4294967295
Long.toUnsignedString(0xFFFFFFFFFF) = 18446744073709551615
Long.toUnsignedString(0x100000000L) = 4294967296
Long.toUnsignedString(0xFFFFFFFFFFFFFFFFL) = 18446744073709551615
Long.toUnsignedString(0x8000000000000000L) = 9223372036854775808
Long.toString(0xFFFFFFFFFFFFFFFFL) = -1
Long.toString(0x8000000000000000L) = -9223372036854775808
*/

 

 

 

 

Posted by Scripter
,

정수부의 자리수가 조금 큰 부동소수점수(64비트 double 포맷의 수)를 십진수 표현으로 출력해 보았습니다.

십진수로 표현하면  유효자리수 개수가 약 14~15개 정도인데,

17개로 자르고 그 뒤는 모두 0으로 출력합니다.

C# 의 것과 비슷하지만 자르는 유효수자 개수가 다릅니다.

Pyhon 이나 C/C++ 의 경우는 자르지 않고 소수점 위 부분을 모두 출력합니다.

 

물론 Java, C#, Python, C, C++ 어느 프로그램 언어든

십진수로 표현할 때 자르는 방법이나 유효수자 아래 부분을 채우는 방법은 다르지만,

덧셈, 뺄셈, 곱셈, 나누셈, 기타 등등에서 유효수자 아래부분의 처리 결과는 대동소이합니다.

 

 

// Filename: Test_Of_Native_Double_Precison_001.java
//
//
// Compile: javac -d . Test_Of_Native_Double_Precison_001.java
// Execute: java Test_Of_Native_Double_Precison_001
// Output:
//                 Math.pow(2, 128) = 340282366920938460000000000000000000000.000000
//                 Math.pow(2, 128) = 340282366920938460000000000000000000000
//     new BigInteger("2").pow(128) = 340282366920938463463374607431768211456
//
//
//  ------------------------------------------------------
//  출처: https://scripting.tistory.com/
//  ------------------------------------------------------


import java.math.BigInteger;
import java.util.Arrays;

public class Test_Of_Native_Double_Precison_001
{
    public static void test_01() 
    {
          double y = Math.pow(2, 128);
          System.out.printf("            Math.pow(2, 128) = %f\n", y);
          System.out.printf("            Math.pow(2, 128) = %.0f\n", y);

          BigInteger z = new BigInteger("2").pow(128);
          System.out.printf("new BigInteger(\"2\").pow(128) = %s\n", z);
    }
    
    public static void main(String[] args)
    {
        test_01();
        System.out.println();
    }
}
Posted by Scripter
,
/**
 * Filename: HelloHangulUTF8.java
 *
 * File Encoding: UTF8
 *
 * Compile: javac HelloHangulUTF8.java
 *
 * Execute: java HelloHangulUTF8]
 *
 * Output:
 *        Hello. world!
 *        안녕하세요?
 *
 * Version
 *     Prompt> java -version
 *        java version "1.8.0_221"
 *        Java(TM) SE Runtime Environment (build 1.8.0_221-b11)
 *        Java HotSpot(TM) Client VM (build 25.221-b11, mixed mode, sharing)
 *
 * os  EnvironmenT: 32but Window 10
 * Installer: jdk-8u221-windows-i586.exe
 *
 * Download: https://java.com/ko/download/help/
 * Document: https://docs.oracle.com/javase/8/docs/
 *
 * Date. 2019. 9. 12
 */
 
public class HelloHangulUTF8 {
    public static void main(String[] args) {
        System.out.println("Hello. world!");
        System.out.println("안녕하세요?");
    }
}

 

32bit 윈도우 10에 최신 안정 버전 JDK 1.8 Update 221 설치하고 UTF8 한글 테스트하기

 

위의 소스를 BOM 없는 UTF8 파일 인코딩으로 저장하면 윈ㄷㅎ우 10의 cmd 터미널에서  컴파일되고 실행된다.

 

 

 

 

 

 

 

Posted by Scripter
,

소스 파일 Hello.java 는 (BOM 마크 없는) UTF-8 인코딩으로 저장되어 있다.

디폴트 인코딩이 한글 윈도우 8.1 은 MS949 이고, Cygwin64 는 UTF-8 이다.

(Cygwin64 의 LANG 환경변수는 컴파일과 실행에 별로 상관 없는 듯 하다.)

Cygwin64 에는 자바가 설치되어 있지 않고 윈도우의 C:\Java7 폴더에 자바가 설치된 것으로 간주한다.

 

$ export PATH=/cygdrive/c/Java7/bin:$PATH

$ export JAVA_HOME=/cygdrive/c/Java7

$ echo $JAVA_HOME
/cygdrive/c/Java7

$ which java
/cygdrive/c/Java7/bin

$ which javac
/cygdrive/c/Java7/bin

 

/*
 * Filename: Hello.java
 *
 * For Cygwin64 on Windows8.1
 *
 * export LANG=ko_KR.EUC-KR
 * Or
 * export LANG=ko_KR.UTF-8
 *
 * Compile: javac -encoding UTF-8 Hello.java
 *
 * Execute: java -Dfile.encoding=UTF-8 Hello
 * Output:
 *        Hello, world!
 *        안녕하세요?
 */

public class Hello {
    public static void main(String[] args) {
        System.out.println("Hello, world!");
        System.out.println("안녕하세요?");
    }
}

 

 

 



 

Posted by Scripter
,

 

Java 언어 소스:

// Filename: TestHexView03.java
//
// Compile: javac TestHexView03.java
// Execute: java TestHexView03 [filename]
//
// Date: 2013. 7. 28.

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

public class TestHexView03 {

    public static void printUsage() {
        System.out.println("java TestHexView03 [filename]");
    }
    
    public static String toHex(byte b) {
        String s = "";
        int x1, x2;
        x1 = (b & 0xF0) >> 4;
        x2 = b & 0x0F;
        if (x1 < 10)
            s += (char)('0' + x1);
        else
            s += (char)((x1 - 10) + 'A');
        if (x2 < 10)
            s += (char)('0' + x2);
        else
            s += (char)((x2 - 10) + 'A');
        return s;
    }

    public static String toHex8(int n) {
        String s = "";
        int x1, x2, x3, x4, x5, x6, x7, x8;
        x1 = (n & 0xF0000000) >> 28;
        x2 = (n & 0xF000000) >> 24;
        x3 = (n & 0xF00000) >> 20;
        x4 = (n & 0xF0000) >> 16;
        x5 = (n & 0xF000) >> 12;
        x6 = (n & 0xF00) >> 8;
        x7 = (n & 0xF0) >> 4;
        x8 = n & 0x0F;
        if (x1 < 10)
            s += (char)(x1 + '0');
        else
            s += (char)((x1 - 10) + 'A');
        if (x2 < 10)
            s += (char)(x2 + '0');
        else
            s += (char)((x2 - 10) + 'A');
        if (x3 < 10)
            s += (char)(x3 + '0');
        else
            s += (char)((x3 - 10) + 'A');
        if (x4 < 10)
            s += (char)(x4 + '0');
        else
            s += (char)((x4 - 10) + 'A');
        s += " ";
        if (x5 < 10)
            s += (char)(x5 + '0');
        else
            s += (char)((x5 - 10) + 'A');
        if (x6 < 10)
            s += (char)(x6 + '0');
        else
            s += (char)((x6 - 10) + 'A');
        if (x7 < 10)
            s += (char)(x7 + '0');
        else
            s += (char)((x7 - 10) + 'A');
        if (x8 < 10)
            s += (char)(x8 + '0');
        else
            s += (char)((x8 - 10) + 'A');
  
        return s;
    }

    public static void main(String[] args) {
     
        if (args.length < 1) {
      printUsage();
      System.exit(1);
        }
     
        String filename = args[0];
     
        File infile = null;
        FileInputStream fileInput = null;

        try { 

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

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

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

            long fileSize = new File(args[0]).length();
            if  (fileSize < 1L) {
                 System.out.println("The file size is zero.");
                 System.exit(1);
            }

            System.out.println("The size of the file \"" + filename + "\" is " + fileSize + ".\n");
             
            fileInput = new FileInputStream(infile);

            long n = 0L;

            int data;
            String dum = "";

            while (n < fileSize  && (data = fileInput.read()) != -1) {
                if (n % 16 == 0L) {
                    System.out.print(toHex8((int) (n & 0xFFFFFFFF)) + ": ");
                }
             
                if (n % 16 != 8L) {
                    System.out.print(" ");
                }
                else {
                    System.out.print("-");
                }
                System.out.print( toHex((byte) (data & 0xFF)) );
                
                if ((data & 0xFF) >= 0x20 && (data & 0xFF) <= 0x7E) {
                    dum += (char)  (data & 0xFF);
                }
                else {
                    dum += ".";
                }
                
                if (n > 0 && n % 16 == 15L) {
                    System.out.print("  |");
                    System.out.print(dum);
                    System.out.print("|");
                    System.out.println();
                    dum = "";
                }
             
                n++;
            }

            if (n > 0 && n % 16 > 0) {
                for (int i = (int)(n % 16); i < 16; i++) {
                    System.out.print("   ");
                }
                System.out.print("  |");
                System.out.print(dum);
                for (int i = (int)(n % 16); i < 16; i++) {
                    System.out.print(" ");
                }
                System.out.print("|");
                System.out.println();
                dum = "";
            }

            fileInput.close();
            
            System.out.println();
            System.out.println("Read " + n + " bytes");
        }
        catch (IOException e) {
            System.out.println("Error message: " + e.getMessage());
        }   
    }
}

 

 

실행 예 1> java TestHexView03 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> java TestHexView03 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
,

아래 처럼 피보나치(Fibonacci) 수 테이블을 출력하는 Java 소스이다.

------------------------------------------------- n F(n) ------------------------------------------------- 0 0 10 55 20 6,765 30 832,040 40 102,334,155 50 12,586,269,025 60 1,548,008,755,920 70 190,392,490,709,135 80 23,416,728,348,467,685 90 2,880,067,194,370,816,120 100 354,224,848,179,261,915,075 110 43,566,776,258,854,844,738,105 120 5,358,359,254,990,966,640,871,840 130 659,034,621,587,630,041,982,498,215 140 81,055,900,096,023,504,197,206,408,605 150 9,969,216,677,189,303,386,214,405,760,200 -------------------------------------------------



 

* Java 소스

// Filename: MakeFibonacciTable_01.java
//
//        1) Show a simple table of Fibonacci numbers.
//        2) Use a linear recursion whose time complexity is o(N).
//
//   Compile: javac MakeFibonacciTable_01.java
//   Execute: java MakeFibonacciTable_01
//
//   Date: 2013. 3. 14.
//  Author: pkim __AT__ scripts ((DOT)) pe ((DOT)) kr

import java.math.*;

public class MakeFibonacciTable_01 {

    private static String toCurrencyString(BigInteger x) {
     String s = x.toString();
     int n = s.length();
     int i = 0;
     if (n <= 3) {
      return s;
     }
     String t = "";
     i = n % 3;
     if (i > 0 && n > 3) {
         t = s.substring(0, n % 3) + ",";
     }
     while (i < n - 3) {
          t += s.substring(i, i + 3) + ",";
          i += 3;
        }
       t += s.substring(i, n);
     return t;
    }

    private static BigInteger fib_aux(int n, int i, BigInteger a, BigInteger b) {
        if (i == 0) {
            return a;
        }
        else {
            BigInteger t = a.add(b);
            a = b;
            b = t;
            return fib_aux(n, i - 1, a, b);
        }
    }

    public static BigInteger fibo1(int n) {
        return fib_aux(n, n, new BigInteger("0"), new BigInteger("1"));
    }
   

     public static void main(String[] args) {
         BigInteger value;
         int i;

         System.out.printf("---------------------------------------------------------\n");
         System.out.printf("   n                                               F(n)    \n");
         System.out.printf("---------------------------------------------------------\n");
         for (i = 0; i <= 150; i++) {
             value = fibo1(i);
             if ((i % 10) == 0) {
                 System.out.printf("%5d   %47s\n", i, toCurrencyString(value));
             }
         }
         System.out.printf("----------------------------------------------------------\n");
         System.out.printf("\n");
    }
}

 

 

 

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 )

 

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

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

아래의 소스는 대부분 버전의 JVM(자바가상기계) 위에서 컴파일 되고 실행되게 작성된 소스이다.

소스 첫 부분에

    final private static int MAX_ITER = 20000;
    final private static double M_EPSILON = 1.0e-15;

라고 선언하였으니 변수 MAX_ITER 와 M_EPSILON 는 상수는 아니지만 상수와 거의 같은 효과를 같는 클래스 소속 변수(스태틱 변수)이다. Java 언어에는 C 언어나 C++ 언어에서 말하는 상수 선언이 없다.

// Filename: TestNthRootApp.java
//
//            Approximate square roots, cubic roots and n-th roots of a given number.
//
// Compile: javac -d . TestNthRootApp.java
// Execute: java TestNthRootApp
//
// Date: 2013. 1. 6.
// Copyright (c) 2013 PH Kim  (pkim __AT__ scripts.pe.kr)


public class TestNthRootApp {

    final private static int MAX_ITER = 20000;
    final private static double M_EPSILON = 1.0e-15;

    /**
     * Compute the n-th root of x to a given scale, x > 0.
     */
    public static double nPow(double a, int n) {
        if (n > 0) {
            if (n == 1)
                return a;
            else {
                if (a == 0.0 || a == 1.0) {
                    return a;
                }
                else if (a == -1.0) {
                    if (n % 2 == 1)
                        return -1.0;
                    else
                        return 1.0;
                }
                else if (a < 0.0) {
                    if (n % 2 == 1)
                        return -nPow(-a, n);
                    else
                        return nPow(-a, n);
                }
                else {
                    double y = 1.0;
                    for (int i = 0; i < n; i++) {
                        y *= a;
                    }
                    return y;
                }
            }
        }
        else if (n == 0) {
            return 1.0;
        }
        else {      //  when n < 0
            if (a == 0.0)
                throw new RuntimeException("Negative powering exception of zero.");
            else {
                if (n == -1)
                    return 1.0/a;
                else
                    return 1.0/nPow(a, -n);
            }
        }
    }

 

    /**
     * Compute the n-th root of x to a given scale, x > 0.
     */
    public static double gPow(double a, int n) {
        if (n > 0) {
            if (n == 1)
                return a;
            else {
                if (a == 0.0 || a == 1.0) {
                    return a;
                }
                else if (a == -1.0) {
                    if (n % 2 == 1)
                        return -1.0;
                    else
                        return 1.0;
                }
                else if (a < 0.0) {
                    if (n % 2 == 1)
                        return -gPow(-a, n);
                    else
                        return gPow(-a, n);
                }
                else {

                    double y = 1.0;
                    double r = a;
                    int m = 8*4 - 1;            ///  8*sizeof(int) - 1;
                    int one = 1;
                    for (int i = 0; i < m; i++) {
                        if ((n & one) == 0) {
                            y *= 1.0;
                        }
                        else {
                            y *= r;
                        }
                        r = r*r;
                        one <<= 1;
                        if (one > n)
                            break;
                    }
                    return y;
                }
            }
        }
        else if (n == 0) {
            return 1.0;
        }
        else {      //  when n < 0
            if (a == 0.0)
                throw new RuntimeException("Negative powering exception of zero.");
            else {
                if (n == -1)
                    return 1.0/a;
                else
                    return 1.0/gPow(a, -n);
            }
        }
    }


    /**
     * Compute the n-th root of x to a given scale, x > 0.
     */
    public static double mPow(double a, int n) {
        if (n > 0) {
            if (n == 1)
                return a;
            else {
                if (a == 0.0 || a == 1.0) {
                    return a;
                }
                else if (a == -1.0) {
                    if (n % 2 == 1)
                        return -1.0;
                    else
                        return 1.0;
                }
                else if (a < 0.0) {
                    if (n % 2 == 1)
                        return -mPow(-a, n);
                    else
                        return mPow(-a, n);
                }
                else {

                    double y = 1.0;
                    double r = a;
                    int m = n;
                    while (m > 0) {
                        if ((m & 0x1) == 1) {
                            y *= r;
                        }
                        r = r*r;
                        m >>= 1;
                    }
                    return y;
                }
            }
        }
        else if (n == 0) {
            return 1.0;
        }
        else {      //  when n < 0
            if (a == 0.0)
                throw new RuntimeException("Negative powering exception of zero.");
            else {
                if (n == -1)
                    return 1.0/a;
                else
                    return 1.0/mPow(a, -n);
            }
        }
    }

 

    /**
     * Compute the square root of x to a given scale, x > 0.
     */
    public static double heronSqrt(double a) {
        if (a < 0.0) {
            throw new RuntimeException("Cannot find the sqrt of a negative number.");
        }
        else if (a == 0.0 || a == 1.0) {
            return a;
        }
        else {
            double x1 = a;
            double x2 = (x1 + a/x1)/2.0;
            double er = x1 - x2;
            int counter = 0;
            while (x1 + er != x1) {
                x1 = x2;
                x2 = (x1 + a/x1)/2.0;
                er = x1 - x2;
                if (Math.abs(er) < Math.abs(M_EPSILON*x1))
                    break;
                counter++;
                if (counter > MAX_ITER)
                    break;
            }
            if (counter >= MAX_ITER)
                throw new RuntimeException("Inaccurate sqrt exception by too many iterations.");
            return x2;
        }
    }

    /**
     * Compute the cubic root of x to a given scale, x > 0.
     */
    public static double newtonCbrt(double a) {
        if (a == 0.0 || a == 1.0 || a == -1.0) {
            return a;
        }
        else if (a < 0.0) {
            return -newtonCbrt(-a);
        }
        else {
            double x1 = a;
            double x2 = (2.0*x1 + a/(x1*x1))/3.0;
            double er = x1 - x2;
            int counter = 0;
            while (x1 + er != x1) {
                x1 = x2;
                x2 = (2.0*x1 + a/(x1*x1))/3.0;
                er = x1 - x2;
                if (Math.abs(er) < Math.abs(M_EPSILON*x1))
                    break;
                counter++;
                if (counter > MAX_ITER)
                    break;
            }
            if (counter >= MAX_ITER)
                throw new RuntimeException("Inaccurate cbrt exception by too many iterations.");
            return x2;
        }
    }

    /**
     * Compute the n-th root of x to a given scale, x > 0.
     */
    public static double newtonNthRoot(int n, double a) {
        if (n == 0) {
            return 1.0;
        }
        else if (n == 1) {
            return a;
        }
        else if (n > 0) {
            if (a == 0.0 || a == 1.0) {
                return a;
            }
            else if (a == -1.0) {
                if (n % 2 == 1)
                    return a;
                else
                    throw new RuntimeException("Cannot find the even n-th root of a negative number.");
            }
            else if (a < 0.0) {
                if (n % 2 == 1)
                    return -newtonNthRoot(n, -a);
                else
                    throw new RuntimeException("Cannot find the even n-th root of a negative number.");
            }
            else if (a < 1.0) {
                return 1.0/newtonNthRoot(n, 1.0/a);
            }
            else {
                double x1 = a;
                double xn = mPow(x1, n - 1);
                double x2 = ((n - 1)*x1 + a/xn)/n;
                double er = x1 - x2;
                int counter = 0;
                while (x1 + er != x1) {
                    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))
                        break;
                    counter++;
                    if (counter > MAX_ITER)
                        break;
                }
                if (counter >= MAX_ITER)
                    throw new RuntimeException("Inaccurate n-th root exception by too many iterations.");
                return x2;
            }
        }
        else {
            if (a == 0.0) {
                throw new RuntimeException("Cannot find the negative n-th root of zero.");
            }
            else {
                return 1.0/newtonNthRoot(-n, a);
            }
        }
    }


    public static void main(String[] args) {

        double x = 16.0;
        double u = Math.sqrt(x);

        System.out.println("[ Testing heronSqrt(double) ]--------------------");
        System.out.println("x = " + x );
        System.out.println("u = sqrt(" + x + ") = " + u );
        double y = heronSqrt(x);
        System.out.println("y = heronSqrt(" + x + ") = " + y );
        System.out.println("y*y = " + y*y );
        System.out.println();

        System.out.println("[ Testing newtonCbrt(double) ]--------------------" );
        x = -216.0;
        System.out.println("x = " + x );
        System.out.println("-exp(log(-x)/3.0) = " + -Math.exp(Math.log(-x)/3.0) );
        double w = newtonCbrt(x);
        System.out.println("w = newtonCbrt(" + x + ") = " + w );
        System.out.println("w*w*w = " + w*w*w );
        System.out.println();

        x = 729000000000.0;
        System.out.println("x = " + x );
        System.out.println("exp(log(x)/3.0) = " + Math.exp(Math.log(x)/3.0) );
        w = newtonCbrt(x);
        System.out.println("w = newtonCbrt(" + x + ") = " + w );
        System.out.println("w*w*w = " + w*w*w );
        System.out.println();

        System.out.println("[ Testing newtonNthRoot(int, double) ]--------------------" );
        double z = newtonNthRoot(3, x);
        System.out.println("x = " + x );
        System.out.println("z = newtonNthRoot(3, " + x + ") = " + z );
        System.out.println("z*z*z = " + z*z*z );
        System.out.println();

        x = 12960000000000000000.0;
        z = newtonNthRoot(4, x);
        System.out.println("x = " + x );
        System.out.println("z = newtonNthRoot(4, x) = newtonNthRoot(4, " + x + ") = " + z );
        System.out.println("z*z*z*z = " + z*z*z*z );
        System.out.println();

        x = 1.0/12960000000000000000.0;
        z = newtonNthRoot(4, x);
        System.out.println("x = " + x );
        System.out.println("exp(log(x)/4.0) = " + Math.exp(Math.log(x)/4.0) );
        System.out.println("z = newtonNthRoot(4, x) = newtonNthRoot(4, " + x + ") = " + z );
        System.out.println("z*z*z*z = " + z*z*z*z );
        System.out.println();


        try {
            x = -4.0;
            System.out.println("[ Test Exception heronSqrt(double) ]--------------------" );
            System.out.println("x = " + x );
            System.out.println("Calculating heronSqrt(" + x + ")" );
            y = heronSqrt(x);
            System.out.println("y = heronSqrt(" + x + ") = " + y );
            System.out.println("y*y = " + y*y );
            System.out.println();
        }
        catch (Exception ex) {
            System.out.println(ex.getMessage() + "\n" + "Caught some exception in calculating heronSqrt(" + x + ")" );
            System.out.println();
        }


        try {
            x = -4.0;
            System.out.println("[ Test Exception in newtonCbrt(double) ]--------------------" );
            System.out.println("x = " + x );
            System.out.println("Calculating newtonCbrt(" + x + ")" );
             = newtonCbrt(x);
            System.out.println("y = newtonCbrt(" + x + ") = " + y );
            System.out.println("y*y*y = " + y*y*y );
            System.out.println();
        }
        catch (Exception ex) {
            System.out.println(ex.getMessage() + "\n" + "Caught some exception in calculating newtonCbrt(" + x + ")");
            System.out.println();
        }


        System.out.println("[ Test calculations by powering ]-----------------------------" );
        x = 200.0;
        z = newtonNthRoot(10, x);
        System.out.println("x = " + x );
        System.out.println("exp(log(x)/10.0) = " + Math.exp(Math.log(x)/10.0) );
        System.out.println("z = newtonNthRoot(10, x) = newtonNthRoot(10, " + x + ") = " + z );
        System.out.println("pow(z, 10) = " + Math.pow(z, 10) );
        System.out.println();

        x = 3001.0;
        z = newtonNthRoot(99, x);
        System.out.println("x = " + x );
        System.out.println("exp(log(x)/99.0) = " + Math.exp(Math.log(x)/99.0) );
        System.out.println("z = newtonNthRoot(99, x) = newtonNthRoot(99, " + x + ") = " + z );
        System.out.println("pow(z, 99) = " + Math.pow(z, 99) );
        System.out.println();

        x = 3001.0;
        z = newtonNthRoot(-99, x);
        System.out.println("x = " + x );
        System.out.println("exp(log(x)/-99.0) = " + Math.exp(Math.log(x)/-99.0) );
        System.out.println("z = newtonNthRoot(-99, x) = newtonNthRoot(-99, " + x + ") = " + z );
        System.out.println("1.0/pow(z, 99) = " + 1.0/Math.pow(z, 99) );
        System.out.println();


        System.out.println("2.1**2.1 = pow(2.1, 2.1) = "  + Math.pow(2.1, 2.1) );
        System.out.println("2.1**(-2.1) = pow(2.1, -2.1) = "  + Math.pow(2.1, -2.1) );
        System.out.println("2.1**2.1 * 2.1**(-2.1) = pow(2.1, 2.1) * pow(2.1, -2.1) = "  + Math.pow(2.1, 2.1)*Math.pow(2.1, -2.1) );
        System.out.println("2.1**2.1 = exp(2.1*log(2.1)) = "  + Math.exp(2.1*Math.log(2.1)) );
        System.out.println("2.1**(-2.1) = exp(-2.1*log(2.1)) = " + Math.exp(-2.1*Math.log(2.1)) );
        System.out.println("2.1**2.1 * 2.1**(-2.1) = exp(2.1*log(2.1)) * exp(-2.1*log(2.1)) = "  + Math.exp(2.1*Math.log(2.1)) * Math.exp(-2.1*Math.log(2.1)) );
        System.out.println();


        int k = 301;
        x = -1.029;
        double t1 = nPow(x, k);
        double t2 = gPow(x, k);
        double t3 = mPow(x, k);
        System.out.println("t1 = nPow(" + x + ", " + k + ") = " + t1 );
        System.out.println("t2 = gPow(" + x + ", " + k + ") = " + t2 );
        System.out.println("t3 = mPow(" + x + ", " + k + ") = " + t3 );
        System.out.println("t1 / t2 = " + (t1 / t2) );
        System.out.println("t1 - t2 = " + (t1 - t2) );
        System.out.println("t1 == t2 ? " + ((t1 == t2) ? "yes" : "no") );
        System.out.println("t1 / t3 = " + (t1 / t3) );
        System.out.println("t1 - t3 = " + (t1 - t3) );
        System.out.println("t1 == t3 ? " + ((t1 == t3) ? "yes" : "no") );
        System.out.println("t2 / t3 = " + (t2 / t3) );
        System.out.println("t2 - t3 = " + (t2 - t3) );
        System.out.println("t2 == t3 ? " + ((t2 == t3) ? "yes" : "no") );
        System.out.println();

        System.out.println("Done.");
    }
}

/*
[ Testing heronSqrt(double) ]--------------------
x = 16.0
u = sqrt(16.0) = 4.0
y = heronSqrt(16.0) = 4.0
y*y = 16.0

[ Testing newtonCbrt(double) ]--------------------
x = -216.0
-exp(log(-x)/3.0) = -6.000000000000001
w = newtonCbrt(-216.0) = -6.0
w*w*w = -216.0

x = 7.29E11
exp(log(x)/3.0) = 9000.000000000004
w = newtonCbrt(7.29E11) = 9000.0
w*w*w = 7.29E11

[ Testing newtonNthRoot(int, double) ]--------------------
x = 7.29E11
z = newtonNthRoot(3, 7.29E11) = 9000.0
z*z*z = 7.29E11

x = 1.296E19
z = newtonNthRoot(4, x) = newtonNthRoot(4, 1.296E19) = 60000.0
z*z*z*z = 1.296E19

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

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

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

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

x = 3001.0
exp(log(x)/99.0) = 1.0842361893258805
z = newtonNthRoot(99, x) = newtonNthRoot(99, 3001.0) = 1.0842361893258805
pow(z, 99) = 3000.9999999999955

x = 3001.0
exp(log(x)/-99.0) = 0.9223082662659932
z = newtonNthRoot(-99, x) = newtonNthRoot(-99, 3001.0) = 0.9223082662659932
1.0/pow(z, 99) = 3001.000000000004

2.1**2.1 = pow(2.1, 2.1) = 4.749638091742242
2.1**(-2.1) = pow(2.1, -2.1) = 0.21054235726688475
2.1**2.1 * 2.1**(-2.1) = pow(2.1, 2.1) * pow(2.1, -2.1) = 0.9999999999999999
2.1**2.1 = exp(2.1*log(2.1)) = 4.749638091742242
2.1**(-2.1) = exp(-2.1*log(2.1)) = 0.21054235726688478
2.1**2.1 * 2.1**(-2.1) = exp(2.1*log(2.1)) * exp(-2.1*log(2.1)) = 1.0

t1 = nPow(-1.029, 301) = -5457.92801577163
t2 = gPow(-1.029, 301) = -5457.928015771692
t3 = mPow(-1.029, 301) = -5457.928015771692
t1 / t2 = 0.9999999999999887
t1 - t2 = 6.184563972055912E-11
t1 == t2 ? no
t1 / t3 = 0.9999999999999887
t1 - t3 = 6.184563972055912E-11
t1 == t3 ? no
t2 / t3 = 1.0
t2 - t3 = 0.0
t2 == t3 ? yes

Done.
*/


 

 

Posted by Scripter
,

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

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

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

Java 언어에서는 java.lang.Math.asin(double) 메소드로 구현되어 있다.

 

/*
 * Filename: TestArcSine.java
 *
 * Compile: javac -d . TestArcSine.java
 * Execute: java TestArcSine
 *
 * Date: 2013. 1. 1.
 * Copyright (c) pkim _AT_ scripts.pe.kr
 */

public class TestArcSine {
        public static double sin(double x)  {
            double y = Math.sin(x);
            return y;
        }

        public static double asin(double x) {
            double y = Math.asin(x);
            return y;
        }

        public static double sinh(double x) {
            double y = Math.sinh(x);
            return y;
        }

        public static double cosh(double x) {
            double y = Math.cosh(x);
            return y;
        }

        public static double asinh(double x)
        {
            double y = Math.log(x + Math.sqrt(x*x + 1));
            return y;
        }

        public static double acosh(double x)
        {
            double y = Math.log(x + Math.sqrt(x*x - 1));
            return y;
        }

        public static void main(String[] args)
        {
            double x = -0.9;
            double y = asin(x);
            System.out.printf("y = asin(%.1g) = %.9f\n", x,  y);
            System.out.printf("sin(y) = sin(%.9f) = %.1g\n",  y, sin(y));
            System.out.printf("\n");

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

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

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

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

u = acosh(1.1) = 0.4435682544
v = asinh(1.1) = 0.9503469298
cosh(u) = cosh(0.4435682544) = 1.1
sinh(v) = sinh(0.9503469298) = 1.1
*/

 

 

Posted by Scripter
,

Lanczos 알고리즘은 Stirlng 공식에 의한 알고리즘 보다 정밀하며, 십진수로 유효숫자 약 15자리 까지는 정확하게 계산해 준다. 단지 exp 함수를 이용하는 부분에서는 exp, sin, pow 함수들의 구현에 따라 오차가 더 있을 수 있다. C 언어에는 long double 타입이 있어서 좀 더 정밀한 계산을 할 수 있지만. Java 언어에는 그렇지 못하여 그냥 double 타입을 사용하였다. 비교를 위해 아파치의 commons의 Math 라이브러라에서 지원하는 Gamma.logGamma 함수를 사용한 결과도 함께 출력하도록 하였다. (commons 라이브러리는 http://commons.apache.org/math/download_math.cgi 에서 다운로드할 수 있다.

commons 2.2와 common 3.0은 차이가 있으며 서로 호환되지 않는다.

우선 import 구문이 서로 다르다.

        import org.apache.commons.math.special.*;     // commons 2.2의 경우

        import org.apache.commons.math3.special.*;     // commons 3.0의 경우

common 2.2의 경우에는 org.apache.commons.math.special.Gamma 클래스에 gamma 라는함수가 있어서 이를 직접 호출하면 되지만, commons 3.0의 경우에는 org.apache.commons.math3.special.Gamma 클래스에 gamma 라는 함수가 없으므로, logGamma 함수와 exp 함수의 합성함수로 계산하였다.


  exp(Gamma.logGamma(double)) 함수와 (자체 구현된) gamma2(double) 함수에 의한 계산 결과를 비교하기 바란다.


/**
 * Filename: TestLanczos_02.java
 *
 * Compile: javac -d . -cp .:commons-math3-3.0.jar TestLanczos_02.java
 * Execute: java -classpath .:commons-math3-3.0.jar TestLanczos_02
 *
 * Note: You can download commons-math3-3.0-bin.tar.gz or commons-math3-3.0-bin.zip
 *         at http://commons.apache.org/math/download_math.cgi
 *
 * ----------------------------------------------------------------------------
 * See: http://www.thinbasic.com/community/showthread.php?11279-Gamma-function
 * See: http://en.wikipedia.org/wiki/Gamma_function
 * See: http://http://jany.tistory.com/53
 * See: http://support.realsoftware.com/listarchives/realbasic-nug/2003-08/msg03123.html
 * ----------------------------------------------------------------------------
 * Date: 2012. 12. 12.
 * Copyright (C) Pil Ho, Kim  (pkim (AT) scripts.pe.kr)
 */

import java.io.*;
import org.apache.commons.math3.special.Gamma;

public class TestLanczos_02 {

     private static double frac(double x) {
         double result;
         if (x >= 0.0)
             result = Math.abs(x) - Math.floor(Math.abs(x));
         else
             result = -(Math.abs(x) - Math.floor(Math.abs(x)));
        return result;
    }

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

    public static void main(String[] args) {
        double y, x = 1.0;

        while (x > 0.0) {
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            String line = null;

            try {
                System.out.printf("Input x(0 to exit): ");
                line = br.readLine();
                x = Double.parseDouble((line));
            }
            catch (IOException ioe) {
                System.err.println("IO error trying to read your input number!");
                System.err.println("Try to input again.");
            }

            if (x == 0.0) {
                break;
            }
            y = gamma2(x);
            System.out.printf(" Gamma(%f) = (%f)! = %30f\n", x, x - 1, y);

            System.out.printf(" Gamma.logGamma(%f) = log((%f)!) = %f\n", x, x - 1, Gamma.logGamma(x));
            System.out.printf(" Math.exp(Gamm.logGamma(%f)) = (%f)! = %30f\n", x, x - 1, Math.exp(Gamma.logGamma(x)));
        }
    }
}

/*
100! =  93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000

Execute: java -classpath .:commons-math3-3.0.jar TestLanczos_02
Result:
Input x(0 to exit): 101
 Gamma(101.000000) = (100.000000)! = 93326215443944150000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.000000
 Gamma.logGamma(101.000000) = log((100.000000)!) = 363.739376
 Math.exp(Gamm.logGamma(101.000000)) = (100.000000)! = 93326215443942250000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.000000
Input x(0 to exit): 0
*/





Posted by Scripter
,

근사 공식

         \frac{\pi}{\sqrt{12}} = \sum^\infty_{k=0} \frac{(-3)^{-k}}{2k+1}

을 이용하여 근사값 계산하는 프로그램을 Java 언어로 작성해 보았다.



/* * Filename: ApproximatePiOverSqrt12.java * * Compile: javac -d . ApproximatePiOverSqrt12.java * Execute: java ApproximatePiOverSqrt12 */ public class ApproximatePiOverSqrt12 { /* Using the series: \frac{\pi}{\sqrt{12}} = \sum^\infty_{k=0} \frac{(-3)^{-k}}{2k+1} BND : 급수에서 합할 항의 개수 */ public static double approximate(int BND) { int i; double sum = 0; double x; x = 1; sum = 1; for (i = 1; i <= BND; i++) { x = - (x / 3); sum = sum + x/(2*i + 1); } return sum; } public static void main(String[] args) { int BOUND = 100; double value1, value2, err; System.out.println( "Approximate the value of PI/sqrt(12)" ); System.out.println( "-------------------------------------------" ); value1 = Math.PI / Math.sqrt(12.0); System.out.println( " Evaluated directly: " + value1 ); value2 = approximate(BOUND); System.out.println( "Estimated by series: " + value2 ); err = value2 - value1; System.out.println( " Error: " + err ); } }


실행 결과:
Approximate the value of PI/sqrt(12)
-------------------------------------------
 Evaluated directly: 0.9068996821171089
Estimated by series: 0.9068996821171091
              Error: 2.220446049250313E-16



Posted by Scripter
,