C#如何在不四舍五入的情况下将双精度数格式化为一位小数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11744264/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
C# How to format a double to one decimal place without rounding
提问by SMULLER
I need to format a double value to one decimal place without it rounding.
我需要将 double 值格式化为一位小数而不四舍五入。
double value = 3.984568438706
string result = "";
What I have tried is:
我尝试过的是:
1)
1)
result = value.ToString("##.##", System.Globalization.CultureInfo.InvariantCulture) + "%";
// returns 3.98%
2)
2)
result = value.ToString("##.#", System.Globalization.CultureInfo.InvariantCulture) + "%";
// returns 4%
3)
3)
result = value.ToString("##.0", System.Globalization.CultureInfo.InvariantCulture) + "%";
// returns 4.0%
4) (Following other suggestions)
4)(遵循其他建议)
value = (value / 100);
result = String.Format("{0:P1}", Math.Truncate(value * 10000) / 10000);
// returns 4.0%
result = string.Format("{0:0.0%}",value); // returns 4.0%
What I need to display is the value 3.9%
我需要显示的是值 3.9%
Thanks for any help in advance.
提前感谢您的任何帮助。
采纳答案by Bob Vale
result=string.Format("{0:0.0}",Math.Truncate(value*10)/10);
回答by Reed Copsey
I would make a utility method to handle this:
我会制作一个实用方法来处理这个问题:
static double Truncate(double value, int digits)
{
double mult = System.Math.Pow(10.0, digits);
return System.Math.Truncate(value * mult) / mult;
}
You could then do:
然后你可以这样做:
result = Truncate(value, 1).ToString("##.#", System.Globalization.CultureInfo.InvariantCulture) + "%";
Note that you may also want Math.Floorinstead of truncate - but it depends on how you want negative values handled.
请注意,您可能还需要Math.Floor而不是 truncate - 但这取决于您希望如何处理负值。
回答by Les
ToString()doesn't do it. You have to add extra code. The other answers show math approaches, my approach below is kind of outside-the-box.
ToString()不这样做。您必须添加额外的代码。其他答案显示了数学方法,我下面的方法有点开箱即用。
string result = value.ToString();
Console.WriteLine("{0}", result.Substring(0, result.LastIndexOf('.') + 2));
This is a fairly simple brute force approach, but it does the trick when the decimal is a '.'. Here's an extension method to ease the pain (and deals with the decimal point).
这是一种相当简单的蛮力方法,但是当小数点是“.”时它会起作用。这是一种减轻痛苦的扩展方法(并处理小数点)。
public static class Extensions
{
public static string ToStringNoTruncate(this double me, int decimalplaces = 1)
{
string result = me.ToString();
char dec = System.Globalization.CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator[0];
return result.Substring(0, result.LastIndexOf(dec) + decimalplaces + 1);
}
}
回答by Jared Peless
( Math.Truncate( ( value * 10 ) ) / 1000 ).ToString( "#.#%" )
回答by Joshua Honig
Just use modulo operator + built in ToString:
只需使用模运算符 + 内置ToString:
result = (value - (value % 0.1)).ToString("N1") + "%";
回答by BJury
I know this is a old thread but I've just had to do this. While the approaches here work I want a easy way to be able to affect a lot of calls so using the Math.Truncate on all the calls to string.format wasn't really a good option.
我知道这是一个旧线程,但我只是不得不这样做。虽然这里的方法有效,但我想要一种能够影响大量调用的简单方法,因此对所有对 string.format 的调用使用 Math.Truncate 并不是一个好的选择。
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.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;
}
}

