在金融应用程序中舍入资金

时间:2015-05-15 15:07:12

标签: c# currency

我正在为处理钱的应用程序编写一些核心类型。简单的金钱类可能如下所示:

public class Money 
{
    private decimal RawAmount { get; set; }
    public Currency Currency { get; set; }
    public decimal Amount
    {
        get
        {
            return Math.Round(RawAmount, 2);
        }
        set
        {
            RawAmount = value;
        }
    }
}

最初我认为这似乎是一个好主意,直​​到我必须根据几个Money.Amounts编写更复杂的值。

问题显然是每个Money实例的数量将被舍入,因此可能会关闭奇数值。

所以我的问题是,在您期望获得圆满输出的情况下,推荐使用金钱的方式是什么?

特别是我想知道:

  1. 有没有办法避免需要在显示它的UI中舍入我的所有值?是否可以通过某些格式化程序类更好地完成它?

  2. 如果我正在处理复杂的计算,那么生成测试值的最佳方法是什么。例如。如果我对decimal属性使用Amount并想要测试10/3的输出,那么您如何建议我检查结果而不仅仅重新计算计算?

  3. 是否可以将每个复合Amount四舍五入?并接受不准确?有没有人有处理财务的应用程序的经验(注意这不是一个严肃的银行应用程序或任何东西,所以也许pence的分数可能不是太大的问题。)

  4. 非常感谢任何输入。

2 个答案:

答案 0 :(得分:2)

我们现在正在让应用程序使用金钱(甚至是外币 - 但不是银行应用程序).​​.....(对不起我的恩惠 - 并且抱歉缺少"公共和#34;代码,我不是确定我是否可以复制和粘贴我工作中的任何内容)

最好的方法就是"询问客户" 。不是您的业务需要知道,每个客户的内部规定是什么。

我知道你不会问外币,所以你可以跳到4)和5),但是对于上下文......:)

1)在内部,我们只使用一种货币。

2)每份工作都是按照固定利率签订的合同(如果是我们的内部货币,可能是1:1 - 因为没有交易者想要用汇率进行推测,所以他们根据签订的合同和工作有固定利率,因为下一份工作,他们可以用不同的费率签订新合同)

3)任何钱都可以追溯到工作岗位合同与率。

4)可以为整个app设置舍入(一个,两个...... n个小数位)有人想要两个小数位,但是一个客户想要看到5个小数)

5)我们正在为gui& reports 进行四舍五入,即便如此,如果点击十进制框,您将看到未包含的值。没有人关心0.1 CZK,但可能关心0.01€(这是0.2 CZK ...奇怪,但人们很奇怪:))

答案 1 :(得分:2)

  

有没有办法避免需要在显示它的UI中舍入我的所有值,我可以通过某些格式化程序类做得更好吗?

是:

public string ToString(string format, IFormatProvider provider)
{
    return Currency + " " + RawAmount.ToString(format, provider);
}
public string ToString(string format)
{
    return ToString(format, NumberFormatInfo.CurrentInfo);
}
public string ToString(IFormatProvider provider)
{
    return ToString("0.00", provider);
}
public override string ToString()
{
    return ToString(provider);
}

你可以超越这个,但现在只是如何呈现这样的对象取决于呈现它的代码(但默认为两位小数)。

  

如果我正在使用复杂的计算,那么生成测试值的最佳方法是什么。例如。如果我使用小数作为我的Amount属性并想测试10/3的输出,你会如何建议我检查结果而不只是重新计算计算?

在课堂外重新计算。 Assert.Equal(10/3, (new Amount(10) / 3).Value);

  

围绕每个复合量金额是要走的路吗?并接受不准确?有没有人有处理金融的应用程序的经验(注意这不是一个严肃的银行应用程序或任何东西,所以也许pence的分数可能不是太大的问题。)

这取决于它被使用的原因。如果你按照给定的价格计算给用户提供的一堆东西,那么你将不得不加上舍入的值,因为你说你向他们收取12.03美元和3.12美元的费用,因此他们预计总计美元15.15因为这是他们被告知的总和,而不是15.16美元,因为当从15.1586美元四舍五入时,这是12.034和3.1246的总和。

如果你正在计算一些小项目,包括货币兑换等,你将不得不保留所有这些小部分,直到接近结束。

您还必须决定是否应用银行家舍入(默认情况下,以及大多数情况下的那个)或学龄儿童舍入(某些客户预期的那种,如果详情在四舍五入之前可以看到它们),或者总是向下舍入(在某些货币变化过渡期间已合法地坚持)。

实际上,对于任何给定的财务流程,哪种四舍五入,到什么程度以及何时应用是需要在该流程的规则中记录的事情之一。在通用课程中,你不能概括它。

如果您打算使用这样的类,那么将它作为对象本身的操作会更有意义:

public Money Round(int decimals, MidpointRounding mode)
{
    return new Money(Currency, Amount.Round(decimals, mode));
}
public Money Round(MidpointRounding mode)
{
    return Round(2, mode);
}
public Money Round(int decimals)
{
    return Round(decimals, MidpointRounding.ToEven);
}
public Money Round()
{
    return Round(2);
}

有;用户代码可以决定何时进行舍入,以及如何进行舍入但具有合理的默认值。

我还建议将这样的课程设为struct,并且绝对要使其成为不可变的。