C#Double-ToString()格式有两个小数位,但没有舍入

如何在C#中将Double格式化为String,以便只有两个小数位?

如果我使用String.Format("{0:0.00}%", myDoubleValue),那么这个数字就会被舍入,我想要一个简单的截断,而不是舍入。我还希望到String的转换是区分区域性的。

500888 次浏览

I use the following:

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

For instance:

If the number is 50.947563 and you use the following, the following will happen:

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

And there's your answer truncated, now to format the string simply do the following:

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

I suggest you truncate first, and then format:

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

Use the constant 100 for 2 digits truncate; use a 1 followed by as many zeros as digits after the decimal point you would like. Use the culture name you need to adjust the formatting result.

You could also write your own IFormatProvider, though I suppose eventually you'd have to think of a way to do the actual truncation.

The .NET Framework also supports custom formatting. This typically involves the creation of a formatting class that implements both IFormatProvider and ICustomFormatter. (msdn)

At least it would be easily reusable.

There is an article about how to implement your own IFormatProvider/ICustomFormatter here at CodeProject. In this case, "extending" an existing numeric format might be the best bet. It doesn't look too hard.

This is working for me

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

The c# function, as expressed by Kyle Rozendo:

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

The following rounds the numbers, but only shows up to 2 decimal places (removing any trailing zeros), thanks to .##.

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/

I know this is a old thread but I've just had to do this. While the other approaches here work, I wanted an easy way to be able to affect a lot of calls to string.format. So adding the Math.Truncate to all the calls to wasn't really a good option. Also as some of the formatting is stored in a database, it made it even worse.

Thus, I made a custom format provider which would allow me to add truncation to the formatting string, eg:

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

The implementation is pretty simple and is easily extendible to other requirements.

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

i use price.ToString("0.00") for getting the leading 0s

Simplest method, use numeric format strings:

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

Following can be used for display only which uses the property of String ..

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

How about adding one extra decimal that is to be rounded and then discarded:

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


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

To what is worth, for showing currency, you can use "C":

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

Output: $1.99

I had that problem with Xamarin Forms and solved it with this:

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

Solution:

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

(indexOfP+1)+2(this number depend on how many number you want to preserve. I give it two because the question owner want.)

Also note the CultureInformation of your system. Here my solution without rounding.

In this example you just have to define the variable MyValue as double. As result you get your formatted value in the string variable NewValue.

Note - Also set the C# using statement:

using System.Globalization;


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


string NewValue = MyValue.ToString(MyFormat);