如何以编程方式从值中删除/添加复合/非复合百分比和固定金额
本文关键字:复合 添加 百分比 金额 删除 编程 方式 | 更新日期: 2023-09-27 17:51:26
有人给我100美元,并告诉我必须按顺序对它进行以下操作:
增加97加5
乘以3%的复利
就变成了(100 + 97 + 5)* 1.3 = 208.06
现在我的问题就在这里,我知道要从208.06回到100,我必须这样做:
208.06/1.3 - (97 + 5) = 100
上面是一个简单的例子,但一旦我开始混合复合、非复合、扁平的数量,以及不仅可以加减值的能力,它就变得非常复杂。例如,如果再次给我100美元,并告诉我必须按顺序应用以下调整,我不确定如何反转它:
1)添加3%的化合物
2)添加4%的化合物
3)减去90
4)减去3
5)添加非化合物3%
6)添加非化合物4%
以上的计算如下:
((100 * (1.03) * (1.04)) - 90 - 3) * (1 + 0.04 + 0.03)
对于上述内容,我不知道如何通过只知道后调整值和添加的6个调整来逆转它。
上面的公式可以简化为,这样更容易理解如何反转:
(100 * 1.03 * (1.04)) - 93 + 7 = 21.21 and to reverse it, we just do:
(100 * 1.03 * (1.04)) - 93 + 7 = 100
我的问题是如何循环遍历它并以正确的顺序应用操作。我是否必须在一个类中存储操作的顺序和它们的数量,然后在每次计算中进行查询?
我已经在Math.StackExchange.com上发布了这篇文章,但他们把它看作一个大公式,不理解从编程的角度来看,我需要循环通过每个调整并将其从总数中取出。这就是我所遇到的问题,但我不清楚如何通过循环进行每个调整来解决它,因为以正确的顺序应用调整非常重要。我不是在寻找解决方案,而是在寻找正确的方向。
这是一个实现。应用它似乎与最初的样本工作,但如果我做我的另一个,它似乎不工作,除非我做错了:
void Main()
{
var ops = new List<Operation>
{
new CompoundInterest(3.0m),
new CompoundInterest(4.0m),
new Subtract(90.0m),
new Subtract(3.0m),
new NoncompoundInterest(3.0m),
new NoncompoundInterest(4.0m)
};
var applied = ops.Aggregate(100m, (acc, o) => o.Apply(acc));
var unapplied = ops.Reverse().Aggregate(applied, (acc, o) => o.Unapply(acc));
}
// Define other methods and classes here
abstract class Operation
{
public abstract decimal Apply(decimal value);
public abstract decimal Unapply(decimal value);
}
class CompoundInterest : Operation
{
public decimal percent {get;set;}
public CompoundInterest(decimal percent)
{
this.percent = percent;
}
public override decimal Apply(decimal value)
{
return value * (1m + percent/100m);
}
public override decimal Unapply(decimal value)
{
return value / (1m + percent/100m);
}
}
class NoncompoundInterest : Operation {
public decimal percent {get;set;}
public NoncompoundInterest(decimal percent)
{
this.percent = percent;
}
public override decimal Apply(decimal value)
{
return value * (percent/100m);
}
public override decimal Unapply(decimal value)
{
return value / (percent/100m);
}
}
class Add : Operation {
public decimal amount {get;set;}
public Add(decimal amount)
{
this.amount = amount;
}
public override decimal Apply(decimal value)
{
return value + amount;
}
public override decimal Unapply(decimal value)
{
return value - amount;
}
}
class Subtract : Operation {
public decimal amount {get;set;}
public Subtract(decimal amount)
{
this.amount = amount;
}
public override decimal Apply(decimal value)
{
return value - amount;
}
public override decimal Unapply(decimal value)
{
return value + amount;
}
}
可以将其视为一个操作列表,每个操作还提供了如何撤销自身的详细信息。大约…
abstract class Operation
{
public abstract decimal Apply(decimal value);
public abstract decimal Unapply(decimal value);
}
class CompoundInterest : Operation
{
public CompoundInterest(decimal percent)
{
this.percent = percent;
}
public override decimal Apply(decimal value)
{
return value * (1m + percent/100m);
}
public override decimal Unapply(decimal value)
{
return value / (1m + percent/100m);
}
}
class NoncompoundInterest : Operation { ... }
class Add : Operation { ... }
class Subtract : Operation { ... }
现在你可以在一个列表中表示你的操作链:
var ops = new List<Operation>
{
new Add(97m),
new Add(5m),
new CompoundInterest(3.0m),
};
var applied = ops.Aggregate(100m, (acc, o) => o.Apply(acc));
var unapplied = ops.Reverse().Aggregate(208.06m, (acc, o) => o.Unapply(acc));
更新: Aggregate()
的工作原理如下:
decimal acc = 100m;
foreach(Operation o in ops)
acc = o.Apply(acc);
decimal applied = acc;
(acc, o) => o.Apply(acc)
是一个lambda表达式,表示给定当前"累加器"(acc
)和序列中的当前项(o
),返回o.Apply(acc)
的函数。"种子"值(100m)用作第一个acc
,然后函数的返回值作为acc
传递给下一个o
,依此类推。