C # Double-소수점 이하 두 자리이지만 반올림이없는 ToString () 형식


153

소수점 이하 두 자리 만 갖도록 C #에서 a Double를 어떻게 형식화 String합니까?

String.Format("{0:0.00}%", myDoubleValue)숫자를 사용 하면 반올림되고 반올림하지 않고 간단한 자르기를 원합니다. 또한 전환 String이 문화에 민감 해지기를 원합니다 .


"문화에 민감한"은 무엇을 의미합니까? 프로그래머가 제공 한 문화 가치에 따라 서식의 결과가 달라져야한다는 의미입니까? 아니면 현재 스레드의 기본 문화권을 사용 하시겠습니까?
CesarGon

답변:


204

나는 다음을 사용한다 :

double x = Math.Truncate(myDoubleValue * 100) / 100;

예를 들어 :

숫자가 50.947563이고 다음을 사용하면 다음이 발생합니다.

- Math.Truncate(50.947563 * 100) / 100;
- Math.Truncate(5094.7563) / 100;
- 5094 / 100
- 50.94

그리고 답을 잘랐습니다. 이제 문자열을 포맷하려면 다음을 수행하십시오.

string s = string.Format("{0:N2}%", x); // No fear of rounding and takes the default number format

3
-1 string.Format문자열을 형식화하는 단계 와 동일한 단계 에서 문화권 구분 형식을 수행 할 수 있습니다 . 아래 답변을 참조하십시오.
CesarGon

1
훌륭합니다. 내 의견이 어리석은 것처럼 보이지 않기를 바랍니다. :-) 그런 다음 downvote를 변경합니다.
CesarGon

1
나에게 문자열 형식에 대한 솔루션이 매우 간단하기 때문에 잘림이 더 까다로 웠습니다.
Kyle Rosendo

1
불행히도 숫자가 1보다 작을 때 솔루션이 제대로 작동하지 않습니다. 0.97,이 상황에 대한 해결 방법이 있습니까?
Ali Dehghan

2
@Jonny는 반올림 때문에 작동하지 않습니다-OP는 반올림하지 않고 자르기를 원합니다. 차이점은 미묘합니다.
BKSpurgeon 17

102

다음 은 숫자를 반올림 하지만으로 인해 소수점 이하 2 자리까지 표시합니다 (마침표 0 제거) .##.

decimal d0 = 24.154m;
decimal d1 = 24.155m;
decimal d2 = 24.1m;
decimal d3 = 24.0m;

d0.ToString("0.##");   //24.15
d1.ToString("0.##");   //24.16 (rounded up)
d2.ToString("0.##");   //24.1  
d3.ToString("0.##");   //24

http://dobrzanski.net/2009/05/14/c-decimaltostring-and-how-to-get-rid-of-trailing-zeros/


12
작동하지 않습니다. 0.2415999로 사용해보십시오. 이 솔루션은 잘리지 않고 반올림합니다.
BJury

5
와우, 너무 많은 투표와 반올림을 사용하고 있습니다. 반올림이 요청 된 가장 가까운 소수 자릿수를 향하고있는 반면, 잘림은 요청 된 가장 가까운 소수점 자르기 후에 잘립니다.
mysticcoder

1
@mysticcoder 내 답변이 내가했던 것과 같은 방식으로 Google 검색에서 ops 질문에 와서 후행 0을 제거하고 ops 질문의 반올림 욕구를 찾지 않기 때문에 많은 답을 얻습니다. 나는 내 대답은 ... 삭제해야합니다 생각
브라이언 오그 덴

@BrianOgden-아니요, 삭제하지 마십시오. 나는 당신의 대답을 찾기 위해 여기에 도착했습니다. +1
Roberto

35

먼저 자른 다음 형식을 지정하는 것이 좋습니다.

double a = 123.4567;
double aTruncated = Math.Truncate(a * 100) / 100;
CultureInfo ci = new CultureInfo("de-DE");
string s = string.Format(ci, "{0:0.00}%", aTruncated);

2 자리 자르기에는 상수 100을 사용하십시오. 원하는 소수점 다음의 숫자만큼 1과 숫자 0을 사용하십시오. 서식 결과를 조정해야하는 문화권 이름을 사용하십시오.


내가 대신의 생각 new CultureInfo("de-DE"), 당신은 정적 속성 사용해야합니다Culture.InvariantCulture
vchan


13

나는 price.ToString("0.00") 0을 얻는 데 사용 합니다.


6

Kyle Rozendo가 표현한 c # 함수 :

string DecimalPlaceNoRounding(double d, int decimalPlaces = 2)
{
    d = d * Math.Pow(10, decimalPlaces);
    d = Math.Truncate(d);
    d = d / Math.Pow(10, decimalPlaces);
    return string.Format("{0:N" + Math.Abs(decimalPlaces) + "}", d);
}

5

반올림 한 다음 버려야 할 소수를 하나 더 추가하는 방법은 다음과 같습니다.

var d = 0.241534545765;
var result1 = d.ToString("0.###%");

var result2 = result1.Remove(result1.Length - 1);

3
그것은 .... 작동하지 대답은 (오늘 현재) 60 개 투표 업을 가지고 있으며,이 매우 간단하고 솔루션 방탄 하나만 얼마나 재미
아서 Kazykhanov

5
반올림이 컷오프 위의 두 자리 이상에 영향을주는 경우에는 작동하지 않습니다. 예를 들어 0.199999는이 코드에서 0.19 대신 0.20으로 끝납니다.
Bernem

4

이것은 나를 위해 일하고있다

string prouctPrice = Convert.ToDecimal(String.Format("{0:0.00}", Convert.ToDecimal(yourString))).ToString();

2

나는 이것이 오래된 실이라는 것을 알고 있지만 방금 이것을해야했습니다. 다른 접근 방식은 효과가 있지만에 대한 많은 호출에 영향을 줄 수있는 쉬운 방법을 원했습니다 string.format. 따라서 Math.Truncate모든 통화에를 추가하는 것은 실제로 좋은 옵션이 아닙니다. 또한 일부 서식이 데이터베이스에 저장되어 있기 때문에 훨씬 더 나빠졌습니다.

따라서 형식 지정 문자열에 잘림을 추가 할 수있는 사용자 지정 형식 공급자를 만들었습니다.

string.format(new FormatProvider(), "{0:T}", 1.1299); // 1.12
string.format(new FormatProvider(), "{0:T(3)", 1.12399); // 1.123
string.format(new FormatProvider(), "{0:T(1)0,000.0", 1000.9999); // 1,000.9

구현은 매우 간단하고 다른 요구 사항으로 쉽게 확장 할 수 있습니다.

public class FormatProvider : IFormatProvider, ICustomFormatter
{
    public object GetFormat(Type formatType)
    {
        if (formatType == typeof (ICustomFormatter))
        {
            return this;
        }
        return null;
    }

    public string Format(string format, object arg, IFormatProvider formatProvider)
    {
        if (arg == null || arg.GetType() != typeof (double))
        {
            try
            {
                return HandleOtherFormats(format, arg);
            }
            catch (FormatException e)
            {
                throw new FormatException(string.Format("The format of '{0}' is invalid.", format));
            }
        }

        if (format.StartsWith("T"))
        {
            int dp = 2;
            int idx = 1;
            if (format.Length > 1)
            {
                if (format[1] == '(')
                {
                    int closeIdx = format.IndexOf(')');
                    if (closeIdx > 0)
                    {
                        if (int.TryParse(format.Substring(2, closeIdx - 2), out dp))
                        {
                            idx = closeIdx + 1;
                        }
                    }
                    else
                    {
                        throw new FormatException(string.Format("The format of '{0}' is invalid.", format));
                    }
                }
            }
            double mult = Math.Pow(10, dp);
            arg = Math.Truncate((double)arg * mult) / mult;
            format = format.Substring(idx);
        }

        try
        {
            return HandleOtherFormats(format, arg);
        }
        catch (FormatException e)
        {
            throw new FormatException(string.Format("The format of '{0}' is invalid.", format));
        }
    }

    private string HandleOtherFormats(string format, object arg)
    {
        if (arg is IFormattable)
        {
            return ((IFormattable) arg).ToString(format, CultureInfo.CurrentCulture);
        }
        return arg != null ? arg.ToString() : String.Empty;
    }
}

2

나는 Xamarin Forms에 그 문제가 있었고 이것을 해결했다.

percent.ToString("0.##"+"%")

1

가치를 위해 통화를 표시하기 위해 다음을 사용할 수 있습니다 "C".

double cost = 1.99;
m_CostText.text = cost.ToString("C"); /*C: format as currentcy */

산출: $1.99


0

나 자신의 IFormatProvider를 작성할 수도 있지만 결국 실제 잘림을 수행하는 방법을 생각해야한다고 생각합니다.

.NET Framework는 사용자 지정 형식도 지원합니다. 여기에는 일반적으로 IFormatProvider 및 ICustomFormatter를 모두 구현하는 형식화 클래스 작성이 포함됩니다 . (msdn)

최소한 쉽게 재사용 할 수있을 것입니다.

CodeProject에 자신의 IFormatProvider / ICustomFormatter를 구현하는 방법에 대한 기사가 있습니다 . 이 경우 기존 숫자 형식을 "확장"하는 것이 가장 좋습니다. 너무 어려워 보이지 않습니다.


0

다음은 String 속성을 사용하는 디스플레이에만 사용할 수 있습니다.

double value = 123.456789;
String.Format("{0:0.00}", value);

이것은 "123.46"을 줄 것이다. 이 질문은 특히 반올림을 요구하지 않습니다.
Tobberoth

0

해결책:

var d = 0.123345678; 
var stringD = d.ToString(); 
int indexOfP = stringD.IndexOf("."); 
var result = stringD.Remove((indexOfP+1)+2);

(indexOfP + 1) +2 (이 숫자는 보존 할 숫자의 수에 따라 다릅니다. 질문 소유자가 원하기 때문에 두 개를줍니다.)


0

시스템 의 CultureInformation 도 참고하십시오 . 반올림하지 않고 내 솔루션.

이 예에서는 변수 MyValue 를 double 로 정의하면 됩니다. 결과적으로 문자열 변수 NewValue 에서 형식화 된 값을 얻습니다 .

참고-C # using 문도 설정하십시오.

using System.Globalization;  

string MyFormat = "0";
if (MyValue.ToString (CultureInfo.InvariantCulture).Contains (CultureInfo.InvariantCulture.NumberFormat.NumberDecimalSeparator))
   {
      MyFormat += ".00";
   }

string NewValue = MyValue.ToString(MyFormat);
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.