2010-04-08 53 views
9

那麼,治「爲了錢,總是十進制」沒有應用微軟開發團隊裏面,因爲如果它是:「爲了錢,總是小數」?

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

Financial.IPmt和所有其他的方法將接收/返回decimal而不是double原樣。

現在我想知道我是否可以使用這些方法而不用擔心發生整體錯誤?

我應該使用其他一些庫來處理財務問題嗎?如果是的話,你能指點我一些好的(用於C#)嗎?

+1

我完全-不-A-VB-用戶的猜測是,財政庫可能存儲處理內部正確,但我不會賭。你需要檢查內部處理是否一致,然後才根據返回類型對其進行譴責。 – Matchu 2010-04-08 22:58:09

+18

我的投票是布爾 - 你要麼有錢,要麼你沒有;-) – scunliffe 2010-04-08 22:58:35

+1

對VB和C來說是一樣的# – Dryadwoods 2010-04-08 22:59:18

回答

3

你可以使用這個類:

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 
} 
+0

您好,什麼是Per變量? – cbp 2014-05-16 06:32:11

+0

@cbp請參閱[PPmt](https://msdn.microsoft.com/en-us/library/microsoft.visualbasic.financial.ppmt.aspx)的VB函數,該函數與此處的'PPmt'函數相匹配(2nd函數),它調用'IPmt'。 – 2016-09-05 13:18:47

10

下面是關於正是這個話題一個有趣的討論:http://www.vbforums.com/showthread.php?t=524101

的方式約1/3撞傷人解釋說,它採用雙因爲VB.NET職能實施工作完全一樣VB6。 VB6沒有小數類型,這就是它使用double的原因。

所以,如果精度很重要,那麼應該不是使用這些函數。

this question的答案有一些有希望的選擇 - 只是忽略了接受的建議使用VB庫的答案。

以前鏈接的問題已經被刪除,所以這裏有一些我引用的建議(注:我沒有嘗試過這些,因人而異)

+0

儘管VB6確實有一種貨幣類型,這是一種帶有四個隱含小數位的Int64。 – 2010-04-08 23:24:33

+0

我決定寫我自己的財務方法與十進制值。 紅色的Gate.s.Net反射器作爲一個有用的工具:D – Dryadwoods 2010-04-09 00:08:50

8

使用decimal對金錢的規則是有幫助的,因爲大多數貨幣都有小數單位。通過使用十進制算術,可以避免引入和累積舍入誤差。

Financial Class functions使用浮點的幾個原因:

  • 他們沒有內部積累 - 他們是基於封閉形式的指數/對數運算,而不是迭代和求和時段上。
  • 他們傾向於不使用或產生精確的十進制值。例如,一個精確的小數年利率除以12個月的付款成爲重複小數。
  • 它們主要用於決策支持,最終對實際簿記幾乎沒有適用性。

Pmt和舍入可以確定名義按月支付的,但一旦確定量,平衡積累 - 付款,適用利息費用等 - 發生在decimal。此外,遲交或預付款,付款假期和其他此類不一致將導致財務職能提供的預計攤銷無效。