我正在处理库存软件,并且还按百分比和金额计算折扣。
我用来转换价格%的代码是:
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%那么它计算总额的价格折扣,如果我输入价格金额,那么它计算的百分比折扣总计
答案 0 :(得分:10)
Math.Round(per, 3)
但是,您的方法中存在两个逻辑错误。您正在使用double
来处理金额和应用的百分比。
double
适合与现实世界中的自然物一起使用,例如你的鼻子长度,或被逮捕的名人与Twitter上出现的关于它的笑话之间的秒数。
金钱和百分比折扣不是自然的东西,而是基于特定编号系统的人为金额。
除了毛里塔尼亚的ouguiyas,马达加斯加的ariaries和马耳他的scudo以及几种过时的货币(如旧英镑,先令和便士)之外,几乎所有这些都是基于小数的。在当前时间使用的三个中,前两个基于基数5(并且在十进制系统中可以表示没有错误),并且最后一个与欧元挂钩,因此无需担心它。
现在,当我们处理现实世界时,我们会遇到问题,因为我们的编号系统位于特定的基础上,因此我们得到的结果如0.33333333333333333333333333333
。
有了金钱,我们只能通过分裂得到这些错误,因为除非我们分开,否则什么都不会对我们造成基数限制错误。
但是double
在内部不使用十进制,它使用二进制。二进制具有不同的数字,导致该点后的循环数字。例如。 0.1
和0.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
而不是float
或double
。要了解更多信息,请阅读浮点精度。
使用
来舍入给定数字 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;