C# 无法从一个值中删除/添加多个税?
我必须从一个值中删除/添加多个税费或调整,以恢复其应用的原始值。我将定义什么是调整: 调整可以是复合或非复合的百分比。也可以是固定的美元金额。也可以将其添加或删除到初始值。我只需要写一部分,从税后价值中倒转税款。我写了一些我可以用来生成测试数据的东西,我还写了一些其他的东西,可以从测试数据生成的税后价值中反转这些调整。我认为我在应用调整和取消应用它们方面做得太过火了。调整是按顺序应用的,因此包含(+7%非复合,+3%复合,+5%非复合)的列表将首先应用7,然后是3,然后是5,在这种情况下,我认为要删除它,我必须向后走,这意味着删除5,然后是3,然后是7。这是我的程序,用于将调整应用于初始值(它应该返回115.21,但在本例中,它返回115.0) Lasse,我再次浏览了这些场景,我已经对此发表了评论,但我相信我用计算器计算错了。在以不同的方式进行计算后,我的数字与你的一致,所有情况都通过了。例如,假设:C# 无法从一个值中删除/添加多个税?,c#,finance,C#,Finance,我必须从一个值中删除/添加多个税费或调整,以恢复其应用的原始值。我将定义什么是调整: 调整可以是复合或非复合的百分比。也可以是固定的美元金额。也可以将其添加或删除到初始值。我只需要写一部分,从税后价值中倒转税款。我写了一些我可以用来生成测试数据的东西,我还写了一些其他的东西,可以从测试数据生成的税后价值中反转这些调整。我认为我在应用调整和取消应用它们方面做得太过火了。调整是按顺序应用的,因此包含(+7%非复合,+3%复合,+5%非复合)的列表将首先应用7,然后是3,然后是5,在这种情况下,我认为
var adjustments = new Adjustment[]
{
new NonCompoundTaxAdjustment(7M),
new NonCompoundTaxAdjustment(3M),
new CompoundTaxAdjustment(-5M)
};
我用计算器(100*1.1)/1.05=104.761904做这个,但后来我试了
100*1.1=110
110 * 0.05 = 5.5
110-5.5=104.5,这与你的计算相符,所以我想你是这样处理的
一个想法:
如果从100中减去7%并按如下方式进行:
100-(100*0.07)=93。现在看来这是不正确的,因为加上7%回来,也就是93*1.07,你不会得到100,你会得到99.51。从100中减去7%实际上应该是100/1.07=93.45,当取93.45*1.07时,返回到100
我被困在这里了
当前代码似乎只能正确处理添加百分比的操作。例如,如果我将+7%添加到200,则得到214,这是正确的;如果返回到200,则代码执行214/1.07,这也是正确的。问题是,如果我想从214中删除7%,代码正在执行.93*200=186,这是不正确的。从200中删除的7%实际上是200/1.07=186.9158878504673。取这个值,乘以7%或186.9158878504673*1.07=200,但如果取186*1.07,我得到的是199.02,不是200。好的,我就是这么做的
我从一个由两个数字组成的公式开始,一个因子和一个偏移量
公式如下所示:
result = input * factor + offset
result = input * 1 + 0
result = input * 1
result = input <-- as expected
公式以因子1和偏移量0开始,因此基本上未调整的公式如下所示:
result = input * factor + offset
result = input * 1 + 0
result = input * 1
result = input <-- as expected
要计算100的数值,在加上税费后,通过公式输入100,得到:
result = 100 * 1.1521 + 0
result = 115.21
要计算115.21的值,在添加税费之前,您可以通过求解输入值来反转公式:
result = input * factor + offset
result - offset = input * factor
(result - offset) / factor = input
input = (result - offset) / factor
因此:
你拿回你的100元
您可以在中测试的代码如下所示:
void Main()
{
var adjustments = new Adjustment[]
{
new CompoundTaxAdjustment(7M),
new NonCompoundTaxAdjustment(3M),
new CompoundTaxAdjustment(5M)
};
var original = 100M;
var formula = Adjustment.GenerateFormula(adjustments);
var result = formula.Forward(original).Dump(); // prints 115,5
var newOriginal = formula.Backward(result).Dump(); // prints 100
}
public abstract class Adjustment
{
public class Formula
{
public decimal Factor = 1.0M;
public decimal Offset;
public decimal Forward(decimal input)
{
return input * Factor + Offset;
}
public decimal Backward(decimal input)
{
return (input - Offset) / Factor;
}
}
public static Formula GenerateFormula(IEnumerable<Adjustment> adjustments)
{
Formula formula = new Formula();
foreach (var adjustment in adjustments)
adjustment.Adjust(formula);
return formula;
}
protected abstract void Adjust(Formula formula);
}
public class FlatValueAdjustment : Adjustment
{
private decimal _Value;
public FlatValueAdjustment(decimal value)
{
_Value = value;
}
protected override void Adjust(Formula formula)
{
formula.Offset += _Value;
}
}
public abstract class TaxAdjustment : Adjustment
{
protected TaxAdjustment(decimal percentage)
{
Percentage = percentage;
}
protected decimal Percentage
{
get;
private set;
}
}
public class CompoundTaxAdjustment : TaxAdjustment
{
public CompoundTaxAdjustment(decimal percentage)
: base(percentage)
{
}
protected override void Adjust(Formula formula)
{
var myFactor = 1M + Percentage / 100M;
formula.Offset *= myFactor;
formula.Factor *= myFactor;
}
}
public class NonCompoundTaxAdjustment : TaxAdjustment
{
public NonCompoundTaxAdjustment(decimal percentage)
: base(percentage)
{
}
protected override void Adjust(Formula formula)
{
formula.Factor += (Percentage / 100M);
}
}
输出:
106,0803000
100
我就是这样做的。它适用于大多数情况,尤其是当您将非复利百分比放在第一位时。如果任何人有任何改进或发现任何错误,请让我知道:
void Main()
{
Adjustment a1 = new Adjustment {Amount = 12.0M, IsCompounded = false, Add = false, Percent = false};
Adjustment a2 = new Adjustment {Amount = 3.0M, IsCompounded = true, Add = true, Percent = true};
Adjustment a3 = new Adjustment {Amount = 5.0M, IsCompounded = true, Add = true ,Percent = true};
List<Adjustment> adjustments = new List<Adjustment>();
adjustments.Add(a3);
adjustments.Add(a2);
adjustments.Add(a1);
decimal total = 103.55987055016181229773462783m;
decimal adjustedTotal = total;
decimal nonCompoundValues = 0.0m;
decimal compoundValues = 1.0m;
string prevType = "";
for(int i = 0; i <= adjustments.Count - 1; i++)
{
if(adjustments[i].Percent)
{
if(adjustments[i].IsCompounded)
{
if(i == adjustments.Count - 1 && adjustments[i].IsCompounded)
{
if(adjustments[i].Add)
{
nonCompoundValues += adjustments[i].Amount/100.0m;
}
else
{
nonCompoundValues -= adjustments[i].Amount/100.0m;
}
break;
}
if(nonCompoundValues < 0 & prevType != "Compound") //Remove tax
{
adjustedTotal /= compoundValues + Math.Abs(nonCompoundValues);
nonCompoundValues = 0.0m;
compoundValues = 1.0m;
}
else if(nonCompoundValues > 0 & prevType != "Compound") //Add tax
{
adjustedTotal *= compoundValues + Math.Abs(nonCompoundValues);
nonCompoundValues = 0.0m;
compoundValues = 1.0m;
}
if(adjustments[i].Add)
{
if(prevType == "" || prevType == "Compound")
{
adjustedTotal *= 1 + adjustments[i].Amount/100.0m; //add compound first
compoundValues = 1.0m;
}
else
{
compoundValues *= 1 + adjustments[i].Amount/100.0m;
}
}
else
{
if(prevType == "" || prevType == "Compound")
{
adjustedTotal /= 1 + adjustments[i].Amount/100.0m;
compoundValues = 1.0m;
}
else
{
compoundValues /= 1 + adjustments[i].Amount/100.0m;
}
}
prevType = "Compound";
}
else // Non-Compound
{
if(adjustments[i].Add)
{
nonCompoundValues += adjustments[i].Amount/100.0m;
}
else
{
nonCompoundValues -= adjustments[i].Amount/100.0m;
}
prevType = "Non-compound";
}
}
else //flat
{
if(nonCompoundValues < 0) //Remove tax
{
adjustedTotal /= compoundValues + Math.Abs(nonCompoundValues);
nonCompoundValues = 0.0m;
compoundValues = 1.0m;
}
else if(nonCompoundValues > 0) //Add tax
{
adjustedTotal *= compoundValues + Math.Abs(nonCompoundValues);
nonCompoundValues = 0.0m;
compoundValues = 1.0m;
}
if(adjustments[i].Add)
{
adjustedTotal += adjustments[i].Amount;
}
else
{
adjustedTotal -= adjustments[i].Amount;
}
}
}
if(nonCompoundValues < 0)
{
adjustedTotal /= compoundValues + Math.Abs(nonCompoundValues);
}
else
{
adjustedTotal *=compoundValues + Math.Abs(nonCompoundValues);
}
Console.WriteLine(adjustedTotal);
}
public class Adjustment
{
public bool Percent {get;set;}
public decimal Amount {get;set;}
public bool IsCompounded {get;set;}
public bool Add{get;set;}
public decimal AmountFraction
{
get {
return Amount/100.0M;
}
}
public decimal CompoundedValue
{
get{
return 1 + AmountFraction;
}
}
}
void Main()
{
调整a1=新调整{金额=12.0M,综合=false,增加=false,百分比=false};
调整a2=新调整{金额=3.0M,综合=true,增加=true,百分比=true};
调整a3=新调整{金额=5.0M,综合=true,增加=true,百分比=true};
列表调整=新列表();
增加(a3);
增加(a2);
增加(a1);
十进制总数=103.5598705501618122977346462783米;
十进制调整总数=总数;
十进制非交换值=0.0m;
十进制复合值=1.0m;
字符串prevType=“”;
对于(int i=0;i 0&prevType!=“复合”)//添加税
{
调整后的总*=复合值+数学绝对值(非复合值);
非冲击值=0.0m;
复合值=1.0m;
}
如果(调整[i]。添加)
{
如果(prevType==“”| | prevType==“复合”)
{
调整后的总量*=1+调整量[i]。金额/100.0m;//首先添加化合物
复合值=1.0m;
}
其他的
{
复合值*=1+调整[i]。金额/100.0m;
}
}
其他的
{
如果(prevType==“”| | prevType==“复合”)
{
调整总数/=1+调整[i]。金额/100.0m;
复合值=1.0m;
}
其他的
{
复合值/=1+调整[i]。金额/100.0m;
}
}
prevType=“复合”;
}
else//非化合物
{
如果(调整[i]。添加)
{
非收购价值+=调整[i]。金额/100.0m;
}
其他的
{
非收购价值-=调整[i]。金额/100.0m;
}
prevType=“非复合”;
}
}
else/平坦
{
if(非合并价值<0)//删除税款
{
调整后的总/=复合值+数学绝对值(非复合值);
非冲击值=0.0m;
复合值=1.0m;
}
else if(非磅值>0)//添加税
{
调整后的总*=复合值+数学绝对值(非复合值);
非冲击值=0.0m;
复合值=1.0m;
}
如果(调整[i]。添加)
{
调整总数+=调整数[i]。金额;
}
其他的
{
void Main()
{
var adjustments = new Adjustment[]
{
new CompoundTaxAdjustment(7M),
new NonCompoundTaxAdjustment(3M),
new CompoundTaxAdjustment(5M)
};
var original = 100M;
var formula = Adjustment.GenerateFormula(adjustments);
var result = formula.Forward(original).Dump(); // prints 115,5
var newOriginal = formula.Backward(result).Dump(); // prints 100
}
public abstract class Adjustment
{
public class Formula
{
public decimal Factor = 1.0M;
public decimal Offset;
public decimal Forward(decimal input)
{
return input * Factor + Offset;
}
public decimal Backward(decimal input)
{
return (input - Offset) / Factor;
}
}
public static Formula GenerateFormula(IEnumerable<Adjustment> adjustments)
{
Formula formula = new Formula();
foreach (var adjustment in adjustments)
adjustment.Adjust(formula);
return formula;
}
protected abstract void Adjust(Formula formula);
}
public class FlatValueAdjustment : Adjustment
{
private decimal _Value;
public FlatValueAdjustment(decimal value)
{
_Value = value;
}
protected override void Adjust(Formula formula)
{
formula.Offset += _Value;
}
}
public abstract class TaxAdjustment : Adjustment
{
protected TaxAdjustment(decimal percentage)
{
Percentage = percentage;
}
protected decimal Percentage
{
get;
private set;
}
}
public class CompoundTaxAdjustment : TaxAdjustment
{
public CompoundTaxAdjustment(decimal percentage)
: base(percentage)
{
}
protected override void Adjust(Formula formula)
{
var myFactor = 1M + Percentage / 100M;
formula.Offset *= myFactor;
formula.Factor *= myFactor;
}
}
public class NonCompoundTaxAdjustment : TaxAdjustment
{
public NonCompoundTaxAdjustment(decimal percentage)
: base(percentage)
{
}
protected override void Adjust(Formula formula)
{
formula.Factor += (Percentage / 100M);
}
}
var adjustments = new Adjustment[]
{
new CompoundTaxAdjustment(1M),
new NonCompoundTaxAdjustment(1M),
new FlatValueAdjustment(1M),
new CompoundTaxAdjustment(1M),
new NonCompoundTaxAdjustment(1M),
new CompoundTaxAdjustment(1M)
};
106,0803000
100
void Main()
{
Adjustment a1 = new Adjustment {Amount = 12.0M, IsCompounded = false, Add = false, Percent = false};
Adjustment a2 = new Adjustment {Amount = 3.0M, IsCompounded = true, Add = true, Percent = true};
Adjustment a3 = new Adjustment {Amount = 5.0M, IsCompounded = true, Add = true ,Percent = true};
List<Adjustment> adjustments = new List<Adjustment>();
adjustments.Add(a3);
adjustments.Add(a2);
adjustments.Add(a1);
decimal total = 103.55987055016181229773462783m;
decimal adjustedTotal = total;
decimal nonCompoundValues = 0.0m;
decimal compoundValues = 1.0m;
string prevType = "";
for(int i = 0; i <= adjustments.Count - 1; i++)
{
if(adjustments[i].Percent)
{
if(adjustments[i].IsCompounded)
{
if(i == adjustments.Count - 1 && adjustments[i].IsCompounded)
{
if(adjustments[i].Add)
{
nonCompoundValues += adjustments[i].Amount/100.0m;
}
else
{
nonCompoundValues -= adjustments[i].Amount/100.0m;
}
break;
}
if(nonCompoundValues < 0 & prevType != "Compound") //Remove tax
{
adjustedTotal /= compoundValues + Math.Abs(nonCompoundValues);
nonCompoundValues = 0.0m;
compoundValues = 1.0m;
}
else if(nonCompoundValues > 0 & prevType != "Compound") //Add tax
{
adjustedTotal *= compoundValues + Math.Abs(nonCompoundValues);
nonCompoundValues = 0.0m;
compoundValues = 1.0m;
}
if(adjustments[i].Add)
{
if(prevType == "" || prevType == "Compound")
{
adjustedTotal *= 1 + adjustments[i].Amount/100.0m; //add compound first
compoundValues = 1.0m;
}
else
{
compoundValues *= 1 + adjustments[i].Amount/100.0m;
}
}
else
{
if(prevType == "" || prevType == "Compound")
{
adjustedTotal /= 1 + adjustments[i].Amount/100.0m;
compoundValues = 1.0m;
}
else
{
compoundValues /= 1 + adjustments[i].Amount/100.0m;
}
}
prevType = "Compound";
}
else // Non-Compound
{
if(adjustments[i].Add)
{
nonCompoundValues += adjustments[i].Amount/100.0m;
}
else
{
nonCompoundValues -= adjustments[i].Amount/100.0m;
}
prevType = "Non-compound";
}
}
else //flat
{
if(nonCompoundValues < 0) //Remove tax
{
adjustedTotal /= compoundValues + Math.Abs(nonCompoundValues);
nonCompoundValues = 0.0m;
compoundValues = 1.0m;
}
else if(nonCompoundValues > 0) //Add tax
{
adjustedTotal *= compoundValues + Math.Abs(nonCompoundValues);
nonCompoundValues = 0.0m;
compoundValues = 1.0m;
}
if(adjustments[i].Add)
{
adjustedTotal += adjustments[i].Amount;
}
else
{
adjustedTotal -= adjustments[i].Amount;
}
}
}
if(nonCompoundValues < 0)
{
adjustedTotal /= compoundValues + Math.Abs(nonCompoundValues);
}
else
{
adjustedTotal *=compoundValues + Math.Abs(nonCompoundValues);
}
Console.WriteLine(adjustedTotal);
}
public class Adjustment
{
public bool Percent {get;set;}
public decimal Amount {get;set;}
public bool IsCompounded {get;set;}
public bool Add{get;set;}
public decimal AmountFraction
{
get {
return Amount/100.0M;
}
}
public decimal CompoundedValue
{
get{
return 1 + AmountFraction;
}
}
}