如何将值舍入到只有3个小数点?

时间:2014-01-25 19:23:10

标签: c# .net visual-studio types

我正在处理库存软件,并且还按百分比和金额计算折扣。

  • 表示当我输入%金额时,它会自动转换为价格#
  • 当我输入价格时,它会自动转换为%#

我用来转换价格%的代码是:

if(txtDiscount.Text == "" || txtGrandTotal.Text == "")
            {
                MessageBox.Show("Please Enter amount in Grand Total",Application.ProductName,MessageBoxButtons.OK,MessageBoxIcon.Information);
            }
            else
            {
              //  double percent;
                double grandTotal;
                double per;
                double txDiscount;

                //percent = Convert.ToInt32(txtPercant.Text);
                grandTotal = Convert.ToInt32(txtGrandTotal.Text);
                txDiscount = Convert.ToInt32(txtDiscount.Text);


                per = txDiscount / grandTotal * 100;

                //per = percent / 100 * grandTotal;

                if (per % 3 != 0)
                    per = (per - per % 3) + 3;


                txtPercant.Text = Convert.ToString(per);

                    ................
                    ................
                    ................
                    ................
                    ................

现在让我们假设如果我输入的金额是“25”,那么它计算的百分比是“2.77777777777778”。我想把它限制在点之后的三位小数,就像我想成为“2.778”或者我想在点之后只显示3位小数的任何意思,任何人都可以帮助我以哪种方式做到这一点?任何建议将不胜感激!!

编辑:

从价格转换为%代码是:

  private void txtDiscount_Leave(object sender, EventArgs e)
        {  
            if(txtDiscount.Text == "" || txtGrandTotal.Text == "")
            {
                MessageBox.Show("Please Enter amount in Grand Total",Application.ProductName,MessageBoxButtons.OK,MessageBoxIcon.Information);
            }
            else
            {
              //  double percent;
                double grandTotal;
                double per;
                double txDiscount;

                //percent = Convert.ToInt32(txtPercant.Text);
                grandTotal = Convert.ToInt32(txtGrandTotal.Text);
                txDiscount = Convert.ToInt32(txtDiscount.Text);


                per = txDiscount / grandTotal * 100;

                //per =  Math.Round(per, 3);
                per = Math.Truncate(per * 1000) / 1000;

                txtPercant.Text = Convert.ToString(per);








                double lblgrandTotal = 0.0;
                double Disconunt = 0.0;
                double netTotal = 0.0;

                lblgrandTotal = Convert.ToDouble(txtGrandTotal.Text);
                Disconunt = Convert.ToDouble(txtDiscount.Text);
                netTotal = grandTotal - Disconunt;

            //netTotal = Convert.ToInt32(grandTotal) - Convert.ToInt32(Discount);

            lblNetTotal.Text = Convert.ToString(netTotal);

            }
        }

从%到价格代码的Cobersion是:

   private void textBox1_Leave(object sender, EventArgs e)
        {
            if (txtPercant.Text == "")
            {
                MessageBox.Show("Please Enter value in Percenent", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            else
            {
                double percent;
                double grandTotal;
                double per;

                percent = Convert.ToDouble(txtPercant.Text);
                grandTotal = Convert.ToDouble(txtGrandTotal.Text);

                per = percent / 100 * grandTotal;

                txtDiscount.Text = Convert.ToString(per);

                double lblgrandTotal = 0.0;
                double Disconunt = 0.0;
                double netTotal = 0.0;

                lblgrandTotal = Convert.ToDouble(txtGrandTotal.Text);
                Disconunt = Convert.ToDouble(txtDiscount.Text);
                netTotal = grandTotal - Disconunt;

                //netTotal = Convert.ToInt32(grandTotal) - Convert.ToInt32(Discount);

                lblNetTotal.Text = Convert.ToString(netTotal);
            }
        }

但我面临的问题是我将%转换为价格和Vise Versa,现在以防万一我在12中加价12.33%,当我加12.33%它转换回11.997价格不是它应该是......它应该是12而不是11.997 ......真的很困惑.. !!

注意:

按价格我的意思是我在计算总折扣的百分比折扣和价格折扣,意味着如果我加12%那么它计算总额的价格折扣,如果我输入价格金额,那么它计算的百分比折扣总计

3 个答案:

答案 0 :(得分:10)

Math.Round(per, 3)

但是,您的方法中存在两个逻辑错误。您正在使用double来处理金额和应用的百分比。

double适合与现实世界中的自然物一起使用,例如你的鼻子长度,或被逮捕的名人与Twitter上出现的关于它的笑话之间的秒数。

金钱和百分比折扣不是自然的东西,而是基于特定编号系统的人为金额。

除了毛里塔尼亚的ouguiyas,马达加斯加的ariaries和马耳他的scudo以及几种过时的货币(如旧英镑,先令和便士)之外,几乎所有这些都是基于小数的。在当前时间使用的三个中,前两个基于基数5(并且在十进制系统中可以表示没有错误),并且最后一个与欧元挂钩,因此无需担心它。

现在,当我们处理现实世界时,我们会遇到问题,因为我们的编号系统位于特定的基础上,因此我们得到的结果如0.33333333333333333333333333333

有了金钱,我们只能通过分裂得到这些错误,因为除非我们分开,否则什么都不会对我们造成基数限制错误。

但是double在内部不使用十进制,它使用二进制。二进制具有不同的数字,导致该点后的循环数字。例如。 0.10.01。大多数情况下,涉及的舍入错误将被取消,但有时它们不会。

因此,在处理金钱时,请始终使用decimal而不是double,除非您有充分的理由(如果您无法解释为何上述情况不适用于您的情况,那么你没有)。

第二个问题是,由于你正在做百分比,你正在进行分工,所以你仍然会得到一些舍入错误。

解决方案是存储多于您需要的小数位数。例如。如果你想精确到3位小数(如你所说),那么存储4。

例如,如果在某个时刻我们将12除以7并四舍五入到三个点,我们将得到1.714。如果我们再次乘以7,我们将得到11.998。然而,如果我们存储了四位小数1.7143并且只显示了1.714,那么再次乘以7会得到我们显示的12.0001(再次舍入到3位)为12。

我们无法避免舍入错误,但我们可以在必要的最后时刻以更高的精度工作,因此舍入错误本身会丢失到四舍五入。

答案 1 :(得分:3)

解决方案:如果您想在小数点后只获得3位数,则可以按照以下步骤操作:

步骤1:将双倍值(百分比)与1000相乘,以便在当前位置的3位数后移动小数点。

第2步:截断小数部分,因为我们不需要使用Math.Truncate()方法在当前小数位后的数字。

步骤3:现在将结果(截断部分)除以1000,将小数点移到3位数之前。

注意:请确保在从DiscountPercentage转换为DiscountPrice之前设置DiscountPrice文本框值zero,反之亦然。

试试这个:

     per = Math.Truncate(per * 1000) / 1000;

编辑:您只添加了一种转化方式:

试试这个:

       if (txtDiscount.Text == "" || txtGrandTotal.Text == "")
        {
            MessageBox.Show("Please Enter amount in Grand Total", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Information);
        }
        else
        {
            //  double percent;
            double grandTotal;
            double per;
            double txDiscount;

            //percent = Convert.ToInt32(txtPercant.Text);
            grandTotal = Convert.ToInt32(txtGrandTotal.Text);
            txDiscount = Convert.ToInt32(txtDiscount.Text);
            per= Convert.ToInt32(txtPercant.Text);
            if (per > 0)
            {

                txtDiscount.Text =((per / 100) * grandTotal).ToString();
            }
            else if (txDiscount > 0)
            {
                per = txDiscount / grandTotal * 100;

                //per =  Math.Round(per, 3);
                per = Math.Truncate(per * 1000) / 1000;

                txtPercant.Text = Convert.ToString(per);
            }

答案 2 :(得分:1)

首先,您必须使用Decimal而不是floatdouble。要了解更多信息,请阅读浮点精度

使用

来舍入给定数字
 decimal percentage = 1.23456;
 decimal roundedValue= Math.Round(percentage, 3);

当然你在四舍五入后会失去一些精确度;如果按照设计,没有超过3个精度数字的百分比,那么这是正确的方法。但是如果没有限制怎么办?那就意味着

decimal square = roundedValue * roundValue;

为您提供与

不同的值
decimal square = percentage * percentage;

所以,人们开始认为也许只能在最后完成舍入。

decimal square = Math.Round(percentage * percentage, 3);

这样更好......但是如果square是另一个乘法或除法的输入怎么办?然后会出现同样的精度问题。

因此,应用程序应该做的是尽可能存储最大精度,但只是在显示器后面为人类输出更好的东西。 这是通过仅在UI层而不是在应用程序层中进行舍入来实现的

Console.WriteLine("{0:F3}", d);

您可以通过为文本框提供计算属性来抽象

public string PercentageDisplay
{
  get { return decimalValue.ToString("{0:F3}"); }
}
///
txtPercant.Text = PercentageDisplay;