如何将值四舍五入到小数点后 3 位?

Posted

技术标签:

【中文标题】如何将值四舍五入到小数点后 3 位?【英文标题】:how to round value to only 3 decimal points? 【发布时间】:2014-01-25 19:23:10 【问题描述】:

我正在开发一种库存软件,并且也在按百分比和金额计算折扣。

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

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

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.997Price,这不是应该是一样的……应该是 12 而不是 11.997……真的很困惑……!!

注意:

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

【问题讨论】:

Math.Round(2.77777777777778, 3) 我想转换每个变量中的值而不是实际值我不知道用户每次输入哪个值兄弟@L.B @L.B 谢谢帮我解决了:) @L.B 这里又出现了一个问题,当我在 Price 中输入 12 时,它显示为 12.33%,当我输入 12.33% 时,它会将其转换回 11.997RS,这与应该是不一样的... :/ How do you round a number to two decimal places in C#? 的可能重复项 【参考方案1】:

Math.Round(per, 3)

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

double 适合用于现实世界中的自然事物,例如鼻子的长度,或者名人被捕与 Twitter 上出现有关该名人的笑话之间的秒数。

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

几乎所有这些都是基于十进制的,除了毛里塔尼亚乌吉亚斯、马达加斯加阿里亚斯和马耳他斯库多,以及几种过时的货币(如旧的英镑、先令和便士)。在当前使用的三个中,前两个是基于 5 的(因此在十进制系统中可以毫无错误地表示),最后一个与欧元挂钩,因此无需担心。

现在,当我们处理现实世界时,我们会遇到问题,因为我们的编号系统是在一个特定的基础上,所以我们会得到像 0.33333333333333333333333333333 这样的结果。

有了钱,我们只能用除法来犯这些错误,因为除非我们除法,否则没有什么会迫使我们犯下底限错误。

但是double 内部不使用十进制,它使用二进制。二进制有不同的数字,导致点后出现重复数字。例如。 0.10.01。大多数情况下,所涉及的舍入误差会抵消,但有时不会。

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

第二个问题是,因为你在做百分比,你在做除法,所以你仍然会得到一些四舍五入的错误。

解决方案是存储比您需要的多一位小数。例如。如果您想精确到小数点后 3 位(如您所说),请存储 4。

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

我们无法避免舍入误差,但我们可以以更高的精度工作直到需要的最新时刻,因此舍入误差本身会因舍入而丢失。

【讨论】:

不错的故事,你应该写一本关于这个主题的书。 :) @Bazzz,到目前为止,我只写过有关宗教和魔法主题的书籍,但如果您有兴趣,请随时在亚马逊上搜索我。【参考方案2】:

解决方案:如果您只想获得小数点后 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);
            

【讨论】:

它确实将小数点限制为 3,但我仍然面临一个问题,当我在 Price 中输入 12 时,它显示 12.33%,当我输入 12.33% 时,它会转换回它到 11.997Price 与应有的不同......它应该是 12 而不是 11.997 @psnLoverCSharp:你能分享一下你正在尝试的代码吗? 是的,先生,编辑问题!! nop 告诉你,我正在计算总计的折扣和价格折扣,这意味着如果我加上 12%,那么它会计算总计的价格折扣,如果我输入价格金额,那么它会计算总计折扣百分比 在 txtGrandTotal 我有总计,我必须在 txtPercent 中计算折扣,我有 % 金额,在 txtDiscount 我有折扣价【参考方案3】:

首先你必须使用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);

这更好...但是如果平方是另一个乘法或除法的输入呢?然后会出现同样的精度损失问题。

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

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

你可以通过为你的文本框提供一个计算属性来抽象它

public string PercentageDisplay

  get  return decimalValue.ToString("0:F3"); 

///
txtPercant.Text = PercentageDisplay;

【讨论】:

以上是关于如何将值四舍五入到小数点后 3 位?的主要内容,如果未能解决你的问题,请参考以下文章

c语言中浮点数四舍五入 。 保留一个浮点数小数点后的6位,第3位要四舍五入。如 1.1234.567到1234.570000

NSNumberFormatter 仅四舍五入到小数点后 3 位

Android-四舍五入到小数点后2位[重复]

要四舍五入保留一位小数,JAVA如何实现

XSLT - 四舍五入到小数点后两位

如何将数值四舍五入后保留两位小数点