是否有更专业的方式呈现以下冗长,错综复杂的尝试提取净值并确定增值税金额,以便所有等于起始总数(tot1)
decimal tot1 = Convert.ToDecimal(typeA) + Convert.ToDecimal(typeB);
decimal netTot = Math.Round(Convert.ToDecimal(tot1) / 1.2m, 2);
decimal vat = tot1 - netTot;
decimal netA = Math.Round(Convert.ToDecimal(typeA) / 1.2m, 2);
decimal netB = Math.Round(Convert.ToDecimal(typeB) / 1.2m, 2);
decimal netAA = netTot - (netA + netB);
decimal netAAA = netAA + netA;
话虽如此,这个代码适用于10个案例中的9个。有时会有正负0.01差异,我不明白为什么
答案 0 :(得分:1)
在操作过程中停止四舍五入,只绕过你得到的最终数字。你得到的问题是当你得到像0.333333之类的数字并在继续数学之前将其四舍五入,在我的例子中,这会丢掉1/3的分数。
好的,这是一个例子,让我们假设出于某种原因你得到这些值:
typeA = 39.5
typeB = 0.5
它总计为40.所以netTot((typeA + typeB)/1.2)将是:
33,333333333333333333333333333333
之后,你把它四舍五入到33.33。 然后,netA(typeA / 1.2)和netB(typeB / 1.2)将是:
netA = 32,916666666666666666666666666667
netB = 0,41666666666666666666666666666667
您将每个分别舍入为32.92和0.42,总计为33,34,与netTot的舍入为33.33不同。
正如你所看到的,你绕过的netA和netB的总和会搞砸数学。
答案 1 :(得分:0)
对值进行舍入有两个原因。
除非上述两种情况之一适用,否则不应在执行计算时进行舍入。
您可能想要检查增值税是否应四舍五入到最接近的分数/便士,或者是否应该仅向上舍入。在澳大利亚,商品及服务税必须四舍五入至最接近的分数,因为政府不想错过这些分数!
我会假设你需要围捕。因此,我不会执行Math.Round(total / 1.2m, 2)
(获取网络),而是Math.Ceiling(total * 100m / 6m) / 100m
(获取增值税)。
所以,说过你最终会遇到一个潜在的问题,试图像这样打破你的数字。
比如说你的输入是typeA = "10.47"
& typeB = "15.27"
然后计算增值税总额将是:
var a_vat = Math.Ceiling(a_tot * 100m / 6m) / 100m;
var a_net = a_tot - a_vat;
var b_vat = Math.Ceiling(b_tot * 100m / 6m) / 100m;
var b_net = b_tot - b_vat;
给出了:
a: 8.72 + 1.75 = 10.47
b: 12.72 + 2.55 = 15.27
两者都很好。
但是尝试聚合它们就可以了:
var ab_tot = a_tot + b_tot;
var ab_vat = Math.Ceiling(ab_tot * 100m / 6m) / 100m;
var ab_net = ab_tot - ab_vat;
21.45 + 4.29 = 25.74
您应该注意10.47 + 15.27 = 25.74
(所以总计加起来),但a
&的单独增值税。 b
不加起来a + b
的增值税总额。
1.75 + 2.55 = 4.30 != 4.29
所以,由于对这样的总数进行任何类型的舍入,你会得到像这样的错误。你无法避免它们。
有两种方法可以解决这个问题。
您可以从包含增值税的单个价格开始,然后通过添加每个组件的增值税来计算总增值税。
或者,您从不包含增值税的单个价格开始,并在最终总计上计算一次增值税。
因此,就我的例子而言,我会做这组计算:
var a_vat = Math.Ceiling(a_tot * 100m / 6m) / 100m;
var b_vat = Math.Ceiling(b_tot * 100m / 6m) / 100m;
var ab_vat = a_vat + b_vat;
var ab_tot = a_tot + b_tot;
var ab_net = ab_tot - ab_vat;