【问题标题】:Formatting a double to two decimal places将双精度格式设置为两位小数
【发布时间】:2013-08-27 10:33:35
【问题描述】:

我一直在尝试将打印出来的答案精确到小数点后两位。所涉及的所有数学运算都必须保持小数点后两位的格式。我已经尝试了一些事情,但我不确定要进行哪些更改才能使这项工作正常进行。

double pdt1 = 239.99;
double pdt1Total;
double pdt2 = 129.75;
double pdt2Total;
double pdt3 = 99.95;
double pdt3Total;
double pdt4 = 350.89;
double pdt4Total;
double wage = 200;
double percentage = 9;
double total;
double answer;
double i = 100;
double a;
double b;
double c;
double d;


Console.Write("Enter number sold of product #1: ");
a = Convert.ToInt32(Console.ReadLine());

Console.Write("Enter number sold of product #2: ");
b = Convert.ToInt32(Console.ReadLine());

Console.Write("Enter number sold of product #3: ");
c = Convert.ToInt32(Console.ReadLine());

Console.Write("Enter number sold of product #4: ");
d = Convert.ToInt32(Console.ReadLine());



pdt1Total = a * pdt1;
pdt2Total = b * pdt2;
pdt3Total = c * pdt3;
pdt4Total = d * pdt4;

total = (pdt1Total + pdt2Total + pdt3Total + pdt4Total);



string.Format("{0:0.00}", total);
string.Format("{0:0.00}", answer = (total * percentage / i) + wage);


Console.WriteLine("Earnings this week: "+answer+"");

【问题讨论】:

  • 您可能不想使用浮点数作为货币 - 舍入错误最终会影响您。似乎没有内置任何东西,但请参阅codeproject.com/Articles/28244/A-Money-type-for-the-CLR 之类的链接以获取灵感。话虽如此,当你开始做百分比计算之类的事情时,你真的无法避免添加更多的小数位......
  • 我需要双打始终保持在小数点后两位,但答案不会反映这一点。所以格式为:209.00(如果您为产品 3 选择 1 个产品,为所有其他产品选择 0,这应该是答案。)
  • 你得到什么答案?
  • 我得到了 108.9955,但现在使用 Damith 的代码它可以工作了。

标签: c# format double


【解决方案1】:
    double d =  3.1493745;
    string s = $"{d:0.00}"; // or $"{d:#.##}"
    Console.WriteLine(s); // Displays 3.15

【讨论】:

    【解决方案2】:

    问题在于,当您对所有带两位小数的数字进行加法和乘法运算时,您希望不会出现舍入错误,但请记住 double 的内部表示是以 2 为底的,而不是以 10 为底的!因此,以 10 为底的 0.1 之类的数字可能以 2 为底:0.101010101010110011... 具有无限个小数(存储在双精度中的值将是一个数字 N,带有:

     0.1-Math.Pow(2,-64) < N < 0.1+Math.Pow(2,-64) 
    

    因此,由于舍入错误,像 12.3 + 0.1 这样的运算可能与 12.4 的 64 位双精度值不同(或 12.456 * 10 可能与 124.56 不同)。 例如,如果您在数据库中将 12.3 +0.1 的结果存储到双精度数字类型的表/列字段中,然后 SELECT WHERE xx=12.4 您可能会意识到您存储的数字不完全是 12.4 并且 Sql 选择将不归还记录; 因此,如果您不能使用十进制数据类型(其内部表示以 10 为底)并且必须使用“双”数据类型,则必须在每次加法或乘法后进行一些规范化:

    double freqMHz= freqkHz.MulRound(0.001); // freqkHz*0.001
    double amountEuro= amountEuro.AddRound(delta); // amountEuro+delta
    
    
        public static double AddRound(this double d,double val)
        {
            return double.Parse(string.Format("{0:g14}", d+val));
        }
        public static double MulRound(this double d,double val)
        {
            return double.Parse(string.Format("{0:g14}", d*val));
        }
    

    【讨论】:

      【解决方案3】:

      我会推荐定点(“F”)格式说明符(如 Ehsan 所述)。请参阅Standard Numeric Format Strings

      使用此选项,您甚至可以设置可配置的小数位数:

      public string ValueAsString(double value, int decimalPlaces)
      {
          return value.ToString($"F{decimalPlaces}");
      }
      

      【讨论】:

        【解决方案4】:

        string.Format 不会改变原始值,但会返回一个格式化的字符串。例如:

        Console.WriteLine("Earnings this week: {0:0.00}", answer);
        

        注意:Console.WriteLine 允许内联字符串格式。以上等价于:

        Console.WriteLine("Earnings this week: " + string.Format("{0:0.00}", answer));
        

        【讨论】:

          【解决方案5】:

          既然你在用货币工​​作,为什么不简单地这样做:

          Console.Writeline("Earnings this week: {0:c}", answer);
          

          这会将答案格式化为货币,所以在我的机器(英国)上它会显示为:

          本周收入:209.00 英镑

          【讨论】:

            【解决方案6】:

            嗯,根据您的需要,您可以选择以下任何一种。输出是针对每个方法编写的

            你可以选择你需要的那个

            这将是圆的

            decimal d = 2.5789m;
            Console.WriteLine(d.ToString("#.##")); // 2.58
            

            这将确保写入 2 个小数位。

            d = 2.5m;
            Console.WriteLine(d.ToString("F")); //2.50
            

            如果你想写逗号,你可以使用这个

            d=23545789.5432m;
            Console.WriteLine(d.ToString("n2")); //23,545,789.54
            

            如果你想返回四舍五入的十进制值,你可以这样做

            d = 2.578m;
            d = decimal.Round(d, 2, MidpointRounding.AwayFromZero); //2.58
            

            【讨论】:

            • 投了反对票,因为这个例子使用了 op 要求的双精度的小数。
            【解决方案7】:

            您可以像这样将double 舍入到小数点后两位:

            double c;
            c = Math.Round(c, 2);
            

            但要小心四舍五入最终会咬你,所以谨慎使用它。

            改为使用decimal 数据类型。

            【讨论】:

            • 我确实尝试过 Math.Round,但结果很快就变得不准确。
            • 为什么在四舍五入时双数和小数有什么区别?
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-04-27
            • 1970-01-01
            • 1970-01-01
            • 2014-06-09
            相关资源
            最近更新 更多