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

김보근·2024년 8월 14일

Unity

목록 보기
66/113
post-thumbnail

TIL (Today I Learned): BigInteger 단위 포맷 문제 해결

오늘은 C#에서 BigInteger 값을 적절한 단위로 포맷하여 문자열로 반환하는 기능을 구현하는 도중 발생한 문제를 해결했습니다.

문제 상황
BigInteger 값을 K(천), M(백만), B(십억) 등의 단위로 포맷하기 위해 다음과 같은 코드를 작성했습니다.

public static string FormatBigInteger(BigInteger number)
{
    if (number < 1000)
    {
        return number.ToString();
    }

    string[] standardSuffixes = {
        "K", "M", "B", "T", "P", "Q", "s", "S", "O", "N",
        "D", "U", "d", "Tt", "Qd", "Qt", "Sx", "Sp", "Oc", "No", "V"
    };

    int exponent = 3;

    for (int i = 0; i < standardSuffixes.Length; i++, exponent += 3)
    {
        BigInteger threshold = BigInteger.Pow(10, exponent);

        if (number < threshold)
        {
            double dividedValue = (double)number / (double)BigInteger.Pow(10, exponent - 3);
            return dividedValue.ToString("0.##") + standardSuffixes[i];
        }
    }

    return ((double)number / (double)BigInteger.Pow(10, exponent - 3)).ToString("0.##") + standardSuffixes[standardSuffixes.Length - 1];
}

하지만 이 코드를 실행했을 때, 1000이 1K로 포맷되지 않고 1M으로 잘못 포맷되는 문제가 발생했습니다. 처음에는 코드 로직에 오류가 있는지 의심했으나, 반복적으로 확인한 결과 로직 자체에는 문제가 없었습니다.

트러블슈팅
이 문제의 원인을 찾기 위해 몇 가지 사항을 점검했습니다.

숫자 포맷 로직: 1000이 1K로 표시되려면, 1000 이하의 값에 대해서는 포맷이 적용되지 않고 그대로 반환되어야 한다고 판단했습니다. 그러나 결과는 1M으로 포맷되었습니다.

Threshold 계산: BigInteger.Pow(10, exponent)를 이용해 계산된 임계값이 의도한 대로 동작하는지 확인했습니다. 여기서 특별한 문제는 발견되지 않았습니다.

Suffix 배열: 문제의 원인이 standardSuffixes 배열에 있음을 알게 되었습니다. 1000에 대해 1K로 포맷하려면, 1000과 비교될 때 K 접미사가 적용되어야 하는데, 1000이 K가 아닌 그 다음 접미사(M)로 포맷된 것이 문제였습니다.

문제 원인
문제는 standardSuffixes 배열에 ""(빈 문자열)이 포함되지 않아서 발생했습니다. 즉, 1000과 같은 숫자가 K 대신 M으로 포맷된 이유는 배열의 첫 번째 항목이 K로 시작했기 때문입니다. 1000에 대해 첫 번째 접미사(K)가 적용되는 것이 아니라, 두 번째 접미사(M)가 적용되어 잘못된 결과를 반환한 것입니다.

해결 방법
이 문제를 해결하기 위해 standardSuffixes 배열의 첫 번째 항목에 빈 문자열 ""을 추가했습니다. 이를 통해 1000이 올바르게 1K로 표시되도록 했습니다.

string[] standardSuffixes = {
    "", "K", "M", "B", "T", "P", "Q", "s", "S", "O", "N",
    "D", "U", "d", "Tt", "Qd", "Qt", "Sx", "Sp", "Oc", "No", "V"
};

이 변경 사항으로 인해:

1,000 → 1K
1,000,000 → 1M
1,000,000,000 → 1B
와 같이 예상한 대로 포맷이 올바르게 작동하게 되었습니다.

결론

오늘의 문제를 통해, 코드를 작성할 때 배열이나 자료 구조의 초기 값 설정이 얼마나 중요한지를 깨달았습니다. 배열의 첫 번째 값이 잘못 설정되면, 이후 로직이 아무리 정확하더라도 최종 결과가 의도와 다르게 나올 수 있습니다. 앞으로도 이런 작은 부분까지 세심하게 체크하는 습관을 기르겠습니다.

profile
게임개발자꿈나무

0개의 댓글