2010-03-16 90 views
112

如何在C#中将Double格式设置为String,以便只有两位小数?C#Double - ToString()格式化,小数点后两位但不舍入

如果我使用String.Format("{0:0.00}%", myDoubleValue)该数字然后舍入,我想要一个简单的截断没有任何舍入。我也想要转换为String文化敏感。

+0

你是什么意思“文化敏感“?这是否意味着格式化的结果必须根据程序员提供的文化价值而变化?或者你想使用当前线程的默认文化吗? – CesarGon

回答

152

我使用以下命令:

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 
+2

-1您可以在格式化字符串的相同'string.Format'步骤中进行文化敏感格式设置。请参阅下面的答案。 – CesarGon

+0

准确地说:海报正在寻求一种包含文化敏感格式的解决方案。你的回答在截断部分是完全可以的,但正如你所指出的那样,“文化变革需要分开完成”。你没有指定如何去做,所以我认为你的答案只回答了部分问题。 – CesarGon

+2

好的没问题,我会简单地发布一个附录。 –

30

我建议你先截断,然后进行格式化:

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); 

使用常数100 2位截断;使用1后跟您希望的小数点后的数字。使用您需要的文化名称来调整格式化结果。

0

你也可以编写你自己的IFormatProvider,但我想最终你不得不想办法去做实际的截断。

.NET Framework还支持自定义格式。这通常涉及创建实现IFormatProvider和ICustomFormatter的格式化类。 (msdn)

至少它很容易重复使用。

有一篇关于如何实现你自己的IFormatProvider/ICustomFormatter here at CodeProject的文章。在这种情况下,“扩展”现有的数字格式可能是最好的选择。它看起来不太难。

5

这是为我工作

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

C#的功能,如凯尔Rozendo表示:

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); 
} 
64
decimal d = 0.241534545765m; 
decimal d2 = 0.241m; 
decimal d3 = 0.2m; 

d.ToString("0.##%");  //24.15% 
d2.ToString("0.##%");  //24.1% 
d3.ToString("0.##%");  //20% 

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

+7

这不起作用。试用0.2415999。这个解决方案轮了,而不是截断。 – BJury

+2

哇,这么多的选票,但它使用舍入。可能有必要指出舍入正在朝向最接近的小数位要求,而截断在要求的最接近的小数位之后切断。 – mysticcoder

+0

@mysticcoder我想我的答案会得到如此多的upvotes,因为他们以Google搜索的方式来处理操作问题,正如我所做的那样,希望去除尾随零,并且不寻找操作问题的四舍五入愿望。我想我应该删除我的答案... –

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; 
    } 
} 
7

我使用price.ToString("0.00") 用于获取前导0

10

最简单的方法,使用数字格式的字符串:

double total = "43.257" 
MessageBox.Show(total.ToString("F")); 
+1

其实这个方法是轮的https://msdn.microsoft.com/en-us/library/dwhawy9k(v=vs.110).aspx#FFormatString – elvin

1

继可以用于仅显示其使用字符串的属性..

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

如何增加一个额外的decima L,该是圆,然后丢弃:

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

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

有趣的是,一个不工作的答案有60个投票权(截至今天),并且这个非常简单和防弹的解决方案只有一个...... –

+0

这对于舍入影响截止点以上多位数的情况不起作用。例如0.199999将以此代码结束为0.20,而不是0.19。 – Bernem

0

到什么是值得的,用于显示货币,你可以使用"C"

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

输出:$1.99

相关问题