[C#] 후행 0 제거

컬렉션에서 일부 필드를 반환했습니다.

2.4200
2.0044
2.0000

나는 같은 결과를 원한다

2.42
2.0044
2

나는로 시도했지만 다른 값 을 반올림하도록 String.Format반환 2.0000하고 설정합니다 N0.



답변

입력이 문자열이면 간단하지 않습니까? 다음 중 하나를 사용할 수 있습니다.

string.Format("{0:G29}", decimal.Parse("2.0044"))

decimal.Parse("2.0044").ToString("G29")

2.0m.ToString("G29")

이것은 모든 입력에서 작동합니다.

업데이트 문서가 명확하게 명시되어 있으므로 정밀도 지정자를 29로 명시 적으로 설정 해야하는 표준 숫자 형식을 확인하십시오 .

그러나 숫자가 10 진수이고 정밀도 지정자를 생략하면 고정 소수점 표기법이 항상 사용되며 후행 0이 유지됩니다.

Konrad 업데이트 는 의견에서 지적했습니다 .

0.000001과 같은 값을주의하십시오. G29 형식은 가장 짧은 방법으로 표시하므로 지수 표기법으로 전환됩니다. string.Format("{0:G29}", decimal.Parse("0.00000001",System.Globalization.CultureInfo.GetCultureInfo("en-US")))결과적으로 “1E-08″이 표시됩니다.


답변

나는 같은 문제에 부딪 쳤지 만 라이브러리에 의해 처리 된 문자열에 대한 출력을 제어 할 수없는 경우. Decimal 유형의 구현에 대한 자세한 내용을 살펴본 후 ( http://msdn.microsoft.com/en-us/library/system.decimal.getbits.aspx 참조 ) 깔끔한 트릭을 얻었습니다 (여기서는 확장으로 방법):

public static decimal Normalize(this decimal value)
{
    return value/1.000000000000000000000000000000000m;
}

소수의 지수 부분이 필요한 것으로 줄어 듭니다. 출력 10 진수에서 ToString ()을 호출하면 후행 0없이 숫자가 기록됩니다.

1.200m.Normalize().ToString();


답변

제 생각에는 사용자 정의 숫자 형식 문자열 을 사용하는 것이 더 안전합니다 .

decimal d = 0.00000000000010000000000m;
string custom = d.ToString("0.#########################");
// gives: 0,0000000000001
string general = d.ToString("G29");
// gives: 1E-13


답변

“G29″과학적 표기법을 피하기 위해이 코드를 사용합니다.

public static string DecimalToString(this decimal dec)
{
    string strdec = dec.ToString(CultureInfo.InvariantCulture);
    return strdec.Contains(".") ? strdec.TrimEnd('0').TrimEnd('.') : strdec;
}

편집 : 시스템 CultureInfo.NumberFormat.NumberDecimalSeparator 사용 :

public static string DecimalToString(this decimal dec)
{
    string sep = CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator;
    string strdec = dec.ToString(CultureInfo.CurrentCulture);
    return strdec.Contains(sep) ? strdec.TrimEnd('0').TrimEnd(sep.ToCharArray()) : strdec;
}


답변

해시 ( #) 기호를 사용하여 필요한 경우 후행 0 만 표시하십시오. 아래 테스트를 참조하십시오.

decimal num1 = 13.1534545765;
decimal num2 = 49.100145;
decimal num3 = 30.000235;

num1.ToString("0.##");       //13.15%
num2.ToString("0.##");       //49.1%
num3.ToString("0.##");       //30%


답변

http://dobrzanski.net/2009/05/14/c-decimaltostring-and-how-to-get-rid-of-trailing-zeros/ 에서 우아한 솔루션을 찾았습니다.

원래

decimal v=2.4200M;

v.ToString("#.######"); // Will return 2.42. The number of # is how many decimal digits you support.


답변

매우 낮은 수준의 접근 방식이지만 빠른 정수 계산 만 사용하고 가장 느린 문자열 구문 분석 및 문화 구분 방법은 사용하지 않는 것이 가장 효과적이라고 생각합니다.

public static decimal Normalize(this decimal d)
{
    int[] bits = decimal.GetBits(d);

    int sign = bits[3] & (1 << 31);
    int exp = (bits[3] >> 16) & 0x1f;

    uint a = (uint)bits[2]; // Top bits
    uint b = (uint)bits[1]; // Middle bits
    uint c = (uint)bits[0]; // Bottom bits

    while (exp > 0 && ((a % 5) * 6 + (b % 5) * 6 + c) % 10 == 0)
    {
        uint r;
        a = DivideBy10((uint)0, a, out r);
        b = DivideBy10(r, b, out r);
        c = DivideBy10(r, c, out r);
        exp--;
    }

    bits[0] = (int)c;
    bits[1] = (int)b;
    bits[2] = (int)a;
    bits[3] = (exp << 16) | sign;
    return new decimal(bits);
}

private static uint DivideBy10(uint highBits, uint lowBits, out uint remainder)
{
    ulong total = highBits;
    total <<= 32;
    total = total | (ulong)lowBits;

    remainder = (uint)(total % 10L);
    return (uint)(total / 10L);
}