TIL(2024,08,13)최종 프로젝트 1차구현 하나씩 만들기

김보근·2024년 8월 13일

Unity

목록 보기
65/113
post-thumbnail

TIL (Today I Learned) : BigInteger 포맷팅 작업

오늘은 C#에서 매우 큰 숫자를 다루는 BigInteger 타입을 사용하여, 숫자를 간결하게 표시하는 방법에 대해 작업했습니다. 특히, 표준 접미사를 사용하여 큰 숫자를 읽기 쉽게 변환하는 함수와, 표준 접미사로 표현할 수 없는 더 큰 숫자에 대해 커스텀 접미사를 적용하는 방법을 구현했습니다.

목표

BigInteger 값을 K (Thousand), M (Million), B (Billion) 등의 표준 접미사로 변환.
V (Vigintillion, 10^63)까지 표준 접미사를 사용하고, 그 이후로는 커스텀 알파벳 조합(aa, ab, ac 등)을 적용하여 무한히 큰 숫자도 표현 가능하게 구현.

public static string FormatBigInteger(BigInteger number)
{
    // 표준 접미사 배열: 각 접미사는 특정 지수에 해당하는 숫자를 나타냄
    string[] standardSuffixes = {
        "K", // Thousand (10^3)
        "M", // Million (10^6)
        "B", // Billion (10^9)
        "T", // Trillion (10^12)
        "P", // Quadrillion (10^15)
        "Q", // Quintillion (10^18)
        "s", // Sextillion (10^21)
        "S", // Septillion (10^24)
        "O", // Octillion (10^27)
        "N", // Nonillion (10^30)
        "D", // Decillion (10^33)
        "U", // Undecillion (10^36)
        "d", // Duodecillion (10^39)
        "Tt", // Tredecillion (10^42)
        "Qd", // Quattuordecillion (10^45)
        "Qt", // Quindecillion (10^48)
        "Sx", // Sexdecillion (10^51)
        "Sp", // Septendecillion (10^54)
        "Oc", // Octodecillion (10^57)
        "No", // Novemdecillion (10^60)
        "V" // Vigintillion (10^63)
    };

    int exponent = 3; // 첫 번째 지수는 10^3, 즉 Thousand (K) 부터 시작

    // 표준 접미사를 적용하는 루프
    for (int i = 0; i < standardSuffixes.Length; i++, exponent += 3)
    {
        // number가 현재 지수에 해당하는 숫자보다 작으면, 그 이전 지수의 접미사를 적용
        if (number < BigInteger.Pow(10, exponent))
        {
            // 숫자를 적절히 나누고, 접미사를 붙여서 반환
            return ((double)number / (double)BigInteger.Pow(10, exponent - 3)).ToString("0.##") + standardSuffixes[i];
        }
    }

    // 표준 접미사 이후의 큰 숫자에 대해 알파벳 조합 접미사를 생성
    string[] extendedSuffixes = GenerateExtendedSuffixes();

    // 확장된 접미사를 적용하는 루프
    for (int i = 0; i < extendedSuffixes.Length; i++, exponent += 3)
    {
        // number가 현재 지수에 해당하는 숫자보다 작으면, 그 이전 지수의 접미사를 적용
        if (number < BigInteger.Pow(10, exponent))
        {
            // 숫자를 적절히 나누고, 접미사를 붙여서 반환
            return ((double)number / (double)BigInteger.Pow(10, exponent - 3)).ToString("0.##") + extendedSuffixes[i];
        }
    }

    // 만약 number가 최대 지수를 넘어서는 경우, 마지막 접미사를 사용하여 반환
    return ((double)number / (double)BigInteger.Pow(10, exponent - 3)).ToString("0.##") + extendedSuffixes[extendedSuffixes.Length - 1];
}

private static string[] GenerateExtendedSuffixes()
{
    List<string> suffixes = new List<string>();

    // 이중 알파벳 접미사 생성: 'aa'부터 'zz'까지
    for (char first = 'a'; first <= 'z'; first++)
    {
        for (char second = 'a'; second <= 'z'; second++)
        {
            suffixes.Add(first.ToString() + second.ToString()); // 예: "aa", "ab", ..., "zz"
        }
    }

    return suffixes.ToArray(); // 배열로 반환
}

주석 설명

standardSuffixes 배열:

표준 접미사를 담은 배열입니다. 이 배열의 각 요소는 특정 숫자 범위에 대응합니다. 예를 들어, "K"는 10^3을, "M"는 10^6을 나타냅니다.

지수 초기화:

exponent 변수는 숫자 크기를 계산할 때 사용됩니다. 첫 번째 값은 3 (즉, 10^3)이며, 이후 반복문에서 3씩 증가합니다.

표준 접미사 적용 루프:

for 루프는 standardSuffixes 배열을 순회하며, 숫자가 해당 범위에 들어올 때 적절한 접미사를 적용합니다.
BigInteger.Pow(10, exponent)를 사용하여 number가 해당 지수보다 작은지를 비교하고, 그 이전 지수의 접미사를 붙여 반환합니다.

확장 접미사 적용 루프:

표준 접미사 이후에도 큰 숫자를 처리할 수 있도록 GenerateExtendedSuffixes 함수에서 생성된 이중 알파벳 접미사를 사용합니다.
표준 접미사와 동일한 방식으로, 숫자 범위에 따라 적절한 접미사를 적용합니다.

GenerateExtendedSuffixes 함수:

이 함수는 aa부터 zz까지의 접미사를 생성합니다.
이중 루프를 사용하여 a부터 z까지의 두 글자 조합을 만들어 리스트에 추가하고, 이를 배열로 반환합니다.

최대 숫자 처리:

만약 number가 매우 큰 값일 경우, 최대 접미사를 붙여서 반환합니다. 이 경우 extendedSuffixes 배열의 마지막 접미사가 적용됩니다.

코드 동작 과정

표준 접미사 적용:

standardSuffixes 배열에는 K부터 V까지 표준 접미사들이 정의되어 있습니다. 이 접미사들은 각각 10^3에서 10^63까지의 숫자를 표현합니다.
루프를 통해 숫자(number)가 해당 접미사에 해당하는 범위에 있는지 확인한 후, 해당 범위에 있으면 그 접미사를 붙여서 반환합니다.

확장 접미사 적용:

V 이후로 숫자가 더 크다면, GenerateExtendedSuffixes() 함수를 통해 생성된 aa, ab, ac 등의 확장 접미사를 적용합니다.
이 접미사들은 10^66, 10^69 등의 숫자에 대해 계속해서 사용할 수 있으며, 기본적으로 a부터 시작해 두 글자 조합으로 확장됩니다.

예외 처리:

만약 숫자가 아주 큰 값이라면, 최대 접미사를 붙여서 반환합니다. 이 경우 extendedSuffixes 배열의 마지막 접미사가 적용됩니다.

결과 예시

1000 → 1K
1000000 → 1M
1000000000 → 1B
1000000000000 → 1T
1000000000000000000000000 → 1S
1000000000000000000000000000000000 → 1d
1000000000000000000000000000000000000000000000 → 1V
1000000000000000000000000000000000000000000000000 → 1aa

핵심 요약

BigInteger 타입의 큰 숫자를 간결하고 읽기 쉽게 변환하기 위해 표준 접미사와 커스텀 접미사를 함께 사용했습니다.
V까지는 실제로 존재하는 표준 접미사를 사용하고, 그 이후의 큰 숫자에 대해서는 알파벳 조합을 사용하여 확장했습니다.
이 방법을 통해 매우 큰 숫자도 일관된 방식으로 표시할 수 있습니다.

결론

이 코드를 통해 BigInteger 값을 읽기 쉽고 간결하게 표현할 수 있으며, 일반적인 숫자 범위뿐만 아니라 매우 큰 숫자도 일관된 방식으로 포맷팅할 수 있습니다. 주석을 통해 코드의 각 부분이 어떻게 작동하는지 명확히 이해할 수 있도록 설명했습니다.

profile
게임개발자꿈나무

0개의 댓글