【问题标题】:C# How to format a double to one decimal place without roundingC#如何在不四舍五入的情况下将双精度位格式化为小数点后一位
【发布时间】:2012-07-31 15:59:39
【问题描述】:

我需要将双精度值格式化为小数点后一位,而不进行四舍五入。

double value = 3.984568438706
string result = "";

我试过的是:

1)

result = value.ToString("##.##", System.Globalization.CultureInfo.InvariantCulture) + "%"; 
// returns 3.98%

2)

result = value.ToString("##.#", System.Globalization.CultureInfo.InvariantCulture) + "%"; 
// returns 4%

3)

 result = value.ToString("##.0", System.Globalization.CultureInfo.InvariantCulture) + "%"; 
 // returns 4.0%

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%

我需要显示的是值 3.9%

提前感谢您的帮助。

【问题讨论】:

  • 看看this
  • 您的意思是要显示3.9%,截断其余的小数点?

标签: c# string-formatting rounding


【解决方案1】:
result=string.Format("{0:0.0}",Math.Truncate(value*10)/10);

【讨论】:

  • 这非常有效。感谢大家的快速回复。
【解决方案2】:

我会创建一个实用方法来处理这个问题:

static double Truncate(double value, int digits)
{
    double mult = System.Math.Pow(10.0, digits);
    return System.Math.Truncate(value * mult) / mult;
}

你可以这样做:

result = Truncate(value, 1).ToString("##.#", System.Globalization.CultureInfo.InvariantCulture) + "%"; 

请注意,您可能还需要Math.Floor 而不是截断 - 但这取决于您希望如何处理负值。

【讨论】:

  • OP 想要一个字符串结果,这不是矫枉过正吗?
  • @KingCronus 这有点工作 - 但它返回所需的值。字符串格式总是会导致舍入,因此它不会返回正确的值。
  • 虽然这可能是基于 OP 的“矫枉过正”,但这对我们来说是一个很好的解决方案。我们需要能够截断到可变的小数位数,而不需要四舍五入。效果很好!
【解决方案3】:

我知道这是一个旧线程,但我不得不这样做。虽然这里的方法有效,但我想要一种简单的方法来影响大量调用,因此对 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.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;
    }
}

【讨论】:

    【解决方案4】:

    ToString() 不这样做。您必须添加额外的代码。其他答案显示了数学方法,我下面的方法有点开箱即用。

    string result = value.ToString();
    Console.WriteLine("{0}", result.Substring(0, result.LastIndexOf('.') + 2));
    

    这是一种相当简单的蛮力方法,但当小数点为“.”时,它就可以解决问题。这是一种缓解痛苦的扩展方法(并处理小数点)。

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

    【讨论】:

      【解决方案5】:
      ( Math.Truncate( ( value * 10 ) ) / 1000 ).ToString( "#.#%" )
      

      【讨论】:

        【解决方案6】:

        只需使用模运算符 + 内置 ToString:

        result = (value - (value % 0.1)).ToString("N1") + "%";
        

        【讨论】:

        • 这不适用于没有小数位的数字(例如 5.0 将变为 4.9)
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-04-16
        • 2022-12-10
        • 1970-01-01
        • 2014-10-10
        • 2021-08-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多