10

ええと、" For money, always decimal " というルールは、Microsoft 開発チーム内では適用されません。

Namespace: Microsoft.VisualBasic
Assembly:  Microsoft.VisualBasic (in Microsoft.VisualBasic.dll)

Financial.IPmt他のすべてのメソッドはそのままではdecimalなくdouble、受信/戻ります。

ラウンドミスを気にせずにこれらの方法を使用できるだろうか?

他のライブラリを使用して財務を処理する必要がありますか? はいの場合、(使用するために)良いものをいくつか教えていただけますC#か?

4

3 に答える 3

10

まさにこのトピックに関する興味深い議論があります: http://www.vbforums.com/showthread.php?t=524101

VB.NET 関数は VB6 とまったく同じように動作するように実装されているため、Double を使用していると誰かが説明しています。VB6 には decimal 型がないため、double を使用します。

したがって、精度が重要な場合は、これらの関数を使用しないでください。

この質問への回答には、有望な代替案がいくつかあります。VB ライブラリの使用を示唆する受け入れられた回答は無視してください。

以前にリンクされた質問は削除されたので、参照していた提案の一部を以下に示します (注: これらは試していません、YMMV)

于 2010-04-08T23:02:05.407 に答える
10

decimalほとんどの通貨には小数点以下の単位があるため、お金に使用するルールは役に立ちます。10 進演算を使用することで、丸め誤差の発生と蓄積を回避できます。

金融クラス関数は、いくつかの理由で浮動小数点を使用します。

  • それらは内部的に蓄積されません。期間にわたる反復や合計ではなく、閉じた形式の指数/対数計算に基づいています。
  • 正確な 10 進数値を使用または生成しない傾向があります。たとえば、正確な小数の年利を 12 か月の支払いで割ると、繰り返し小数になります。
  • これらは主に意思決定支援を目的としており、実際の簿記にはほとんど適用できません。

Pmtおよび丸めにより名目上の月々の支払額が決定される場合がありますが、その金額が決定されると、残高の累積 (支払いが行われ、利子が適用されるなど) が で発生しdecimalます。また、支払いの遅延または前払い、支払いの猶予、およびその他の不均一性は、財務機能によって提供される予測償却を無効にする可能性があります。

于 2010-04-09T00:11:48.267 に答える
4

このクラスを使用できます:

public class Financial
{
    #region Methods

    public static decimal IPmt(decimal Rate, decimal Per, decimal NPer, decimal PV, decimal FV, FinancialEnumDueDate Due)
    {
        decimal num;
        if (Due != FinancialEnumDueDate.EndOfPeriod)
        {
            num = 2;
        }
        else
        {
            num = 1;
        }
        if ((Per <= 0) || (Per >= (NPer + 1)))
        {
            //Argument_InvalidValue1=

            throw new ArgumentException("Argument 'Per' is not a valid value.");
        }
        if ((Due != FinancialEnumDueDate.EndOfPeriod) && (Per == 1))
        {
            return 0;
        }
        decimal pmt = Pmt(Rate, NPer, PV, FV, Due);
        if (Due != FinancialEnumDueDate.EndOfPeriod)
        {
            PV += pmt;
        }
        return (FV_Internal(Rate, Per - num, pmt, PV, FinancialEnumDueDate.EndOfPeriod) * Rate);
    }

    public static decimal PPmt(decimal Rate, decimal Per, decimal NPer, decimal PV, decimal FV, FinancialEnumDueDate Due)
    {
        if ((Per <= 0) || (Per >= (NPer + 1)))
        {
            throw new ArgumentException("Argument 'Per' is not valid.");
        }
        decimal num2 = Pmt(Rate, NPer, PV, FV, Due);
        decimal num = IPmt(Rate, Per, NPer, PV, FV, Due);
        return (num2 - num);
    }

    static decimal FV_Internal(decimal Rate, decimal NPer, decimal Pmt, decimal PV, FinancialEnumDueDate Due)
    {
        decimal num;
        if (Rate == 0)
        {
            return (-PV - (Pmt * NPer));
        }
        if (Due != FinancialEnumDueDate.EndOfPeriod)
        {
            num = 1 + Rate;
        }
        else
        {
            num = 1;
        }
        decimal x = 1 + Rate;
        decimal num2 = (decimal)Math.Pow((double)x, (double)NPer);
        return ((-PV * num2) - (((Pmt / Rate) * num) * (num2 - 1)));
    }

    static decimal Pmt(decimal Rate, decimal NPer, decimal PV, decimal FV, FinancialEnumDueDate Due)
    {
        decimal num;
        if (NPer == 0)
        {
            throw new ArgumentException("Argument NPer is not a valid value.");
        }
        if (Rate == 0)
        {
            return ((-FV - PV) / NPer);
        }
        if (Due != FinancialEnumDueDate.EndOfPeriod)
        {
            num = 1 + Rate;
        }
        else
        {
            num = 1;
        }
        decimal x = Rate + 1;
        decimal num2 = (decimal)Math.Pow((double)x, (double)NPer);
        return (((-FV - (PV * num2)) / (num * (num2 - 1))) * Rate);
    }

    #endregion Methods
}
于 2010-07-20T13:21:43.257 に答える