派生小数类型 - 固定精度

时间:2010-12-24 10:29:25

标签: .net decimal currency fixed-point

在.NET中是否有办法创建一个从十进制派生的类型,用作货币,因此它将算术运算舍入到所需的小数点数。

如果没有,.NET中最好的做法是什么?

编辑(动机):

假设我有一个价格:

125.00 Rep$

我卖出了0.25件,相当于31.25

现在,我有15%的折扣,并计算折扣并以绝对值显示我将:

31.25 * .85 = 26.5625

如果我使用其他方式:

31.25 * .15 = 4.6875

如果我让某些第三方控件截断并显示它,例如,我可以:

26.56 +
 4.68 =
-----
31.24

如果你给她这样的东西,每个会计师都会吃掉你的壁炉。

在此处添加税,问题会进一步增加。

所以,NO存储尽可能多的小数并尽可能地舍入它。创建一个经济上正确的类,并尽快将其存储为舍入/截断。

3 个答案:

答案 0 :(得分:3)

你当然不能创建一个派生自decimal的类型,因为它是一个结构 - 你不能创建结构的子类型。

可以创建自己的Currency结构,其中包含小数。你想要重载所有算术运算符,基本上对包含的十进制值执行算术,然后适当地舍入。

例如:

public struct Currency
{
    private readonly decimal value;

    public Currency(decimal value)
    {
        this.value = decimal.Round(value, 2);
    }

    public override string ToString()
    {
        return value.ToString();
    }

    public static Currency operator+(Currency left, Currency right)
    {
        return new Currency(left.value + right.value);
    }

    public static Currency operator-(Currency left, Currency right)
    {
        return new Currency(left.value - right.value);
    }

    public static Currency operator/(Currency left, int right)
    {
        return new Currency(left.value / right);
    }
}

class Test
{
    static void Main()
    {
        Currency currency = new Currency(15);
        Console.WriteLine(currency / 10); // Prints 1.5
        Console.WriteLine(currency / 100); // Prints 0.15
        Console.WriteLine(currency / 1000); // Prints 0.2
    }
}

(显然这里需要更多 - 特别是你要覆盖GetHashCodeEquals,实施IEquatable<T>等。

这绝对是你想要的吗?我认为在中间操作期间保持尽可能多的精确度是更常见的,并且仅在最后时刻进行,例如,用于存储在数据库中或显示给用户。

答案 1 :(得分:1)

您建议的内容无法直接完成(从decimal等值类型派生)。这也不是一个好主意,因为每次算术运算后的舍入都会在最终结果中引入越来越大的错误。

如果我理解正确,最好通过正常使用decimal,最后使用System.Math.Round 一次来进行舍入。

答案 2 :(得分:0)

如果使用:The Currency ("C") Format Specifier输出小数值,System.Decimal应该已经拥有了你需要的东西。