본문 바로가기
자바(Java)

자바에서 큰 수의 팩토리얼을 계산하는 프로그램

by 코딩하는 욤욤이 2024. 11. 9.
반응형

팩토리얼이란?

팩토리얼은 어떤 정수 n에 대해, 1부터 n까지의 모든 양의 정수를 곱한 결과를 의미합니다. 팩토리얼은 보통 n!로 표시됩니다. 예를 들어, 5!는 다음과 같습니다:

5!=5×4×3×2×1

큰 수의 팩토리얼 계산의 어려움

작은 수의 팩토리얼은 쉽게 계산할 수 있지만, 숫자가 커지면 결과값도 매우 커지게 됩니다. 예를 들어:

  • 10!=
  • 20!=

이처럼 숫자가 커지면 자바의 기본 자료형(int나 long)으로는 표현할 수 없게 됩니다. 그래서 아주 큰 값도 처리할 수 있는 방법이 필요합니다.

큰 수의 팩토리얼을 계산하는 방법

큰 수의 팩토리얼을 계산하는 방법은 두 가지가 있습니다:

  1. BigInteger 클래스 사용하기: 자바에서는 BigInteger 클래스를 이용하여 매우 큰 정수도 다룰 수 있습니다.
  2. 배열을 사용하여 직접 계산하기: 각 자릿수를 배열에 저장해서 계산하는 방법입니다. 이 방법은 조금 더 복잡하지만 교육적인 가치가 있습니다.

두 가지 방법을 차례대로 설명드리겠습니다.


1. BigInteger 클래스 사용하기

BigInteger 클래스는 자바의 java.math 패키지에 있으며, 정수 크기의 제한 없이 큰 수를 다룰 수 있습니다.

BigInteger를 이용한 팩토리얼 계산 방법

  1. BigInteger 클래스 가져오기: java.math.BigInteger를 import합니다.
  2. 결과값 초기화: BigInteger 변수에 초기값으로 1을 설정합니다. (팩토리얼 계산은 1부터 시작하므로)
  3. 곱셈 반복: 1부터 n까지 반복하면서, 매번 결과값에 현재 숫자를 곱합니다.
  4. 결과 출력: 반복이 끝나면 팩토리얼 결과를 출력합니다.

BigInteger를 사용한 자바 코드

import java.math.BigInteger;
import java.util.Scanner;

public class FactorialBigInteger {
    public static void main(String[] args) {
        // 사용자로부터 숫자를 입력받습니다.
        Scanner scanner = new Scanner(System.in);
        System.out.print("팩토리얼을 계산할 숫자를 입력하세요: ");
        int n = scanner.nextInt();
        scanner.close();

        // BigInteger를 사용하여 결과값 초기화
        BigInteger factorial = BigInteger.ONE;

        // 팩토리얼 계산을 위한 반복문
        for (int i = 1; i <= n; i++) {
            factorial = factorial.multiply(BigInteger.valueOf(i));
        }

        // 결과 출력
        System.out.println(n + "! = " + factorial);
    }
}

코드 설명

  • BigInteger 초기화: BigInteger.ONE으로 초기화하여 1로 시작합니다.
  • 곱셈 반복문: 1부터 n까지의 정수 i에 대해 factorial에 i를 곱해 나갑니다.
    • BigInteger.valueOf(i)는 정수 i를 BigInteger로 변환해 주어 곱셈을 할 수 있게 해줍니다.
  • 결과 출력: 반복문이 끝나면 최종 결과값이 저장된 factorial을 출력합니다. 이 방법은 간단하고 효율적입니다.

2. 배열을 이용한 직접 계산 (수작업 방식)

교육적인 목적으로, BigInteger 없이 큰 팩토리얼을 계산하는 방법도 소개드리겠습니다. 이 방법은 각 자릿수를 배열에 저장하여 큰 숫자 계산을 시뮬레이션하는 방식입니다.

배열을 사용하여 팩토리얼 계산 방법

  1. 결과를 저장할 배열 초기화: 배열을 생성하여 각 자릿수를 저장합니다. 예를 들어, n!=이면 배열에 [1, 2, 0]과 같이 저장합니다.
  2. 곱셈 반복: 1부터 n까지의 숫자로 각 자릿수를 곱하고 배열에 결과를 갱신합니다.
  3. 자리 올림 처리: 곱셈 결과가 10 이상이 되면 다음 자리로 넘겨주는(자리 올림) 작업을 합니다.
  4. 결과 출력: 배열에 저장된 숫자들을 뒤집어서 출력합니다.

배열을 사용한 자바 코드

import java.util.Scanner;

public class FactorialArray {
    public static void main(String[] args) {
        // 사용자로부터 숫자를 입력받습니다.
        Scanner scanner = new Scanner(System.in);
        System.out.print("팩토리얼을 계산할 숫자를 입력하세요: ");
        int n = scanner.nextInt();
        scanner.close();

        // 배열을 사용하여 결과를 저장할 공간을 초기화합니다.
        int[] result = new int[500]; // 최대 500 자리까지 저장할 수 있는 배열
        result[0] = 1;  // 0! 또는 1!의 값은 1이므로 초기값을 1로 설정
        int resultSize = 1; // 현재 결과의 자리수

        // 2부터 n까지 곱하여 팩토리얼을 계산합니다.
        for (int i = 2; i <= n; i++) {
            resultSize = multiply(i, result, resultSize);
        }

        // 배열을 거꾸로 출력하여 팩토리얼 값 표시
        System.out.print(n + "! = ");
        for (int i = resultSize - 1; i >= 0; i--) {
            System.out.print(result[i]);
        }
        System.out.println();
    }

    // 현재 팩토리얼 결과를 숫자 x와 곱하는 메서드
    private static int multiply(int x, int[] result, int resultSize) {
        int carry = 0;

        // 현재 자릿수와 x를 곱하여 결과를 배열에 저장합니다.
        for (int i = 0; i < resultSize; i++) {
            int product = result[i] * x + carry;
            result[i] = product % 10; // 곱셈 결과의 1의 자리를 저장
            carry = product / 10; // 나머지는 자리 올림으로 저장
        }

        // 자리 올림이 있는 경우 처리하여 배열에 추가
        while (carry != 0) {
            result[resultSize] = carry % 10;
            carry = carry / 10;
            resultSize++;
        }
        return resultSize;
    }
}

코드 설명

  1. 배열 초기화: 배열 result는 최대 500자리까지 저장할 수 있도록 설정되었습니다.
  2. 곱셈 메서드 (multiply): 배열의 각 자리수에 곱셈을 적용합니다.
    • 곱셈 결과가 10 이상이면 다음 자리로 자리 올림(carry)을 합니다.
  3. 결과 출력: 결과 배열을 역순으로 출력하여 팩토리얼 값을 나타냅니다.

이 방식은 좀 더 복잡하지만 큰 수의 곱셈 과정을 깊이 이해하는 데 도움이 됩니다.


  • BigInteger 사용 방법은 간단하고 효율적이므로 실무에서 권장됩니다.
  • 배열을 사용하는 방법은 수학적인 원리를 이해하는 데 유용하며, 큰 수 계산의 내부 동작을 공부하는 데 적합합니다.

두 방법 모두 같은 결과를 제공하지만, 실제 프로그램에서는 BigInteger를 사용하는 것이 더 쉽고 빠릅니다. 설명이 도움이 되었길 바랍니다! 추가로 궁금한 점이 있으시면 언제든지 질문해 주세요!

반응형