2010-04-08 14 views
9

Bueno, la regla "Por dinero, siempre decimales" no se aplica en el interior del equipo de desarrollo de Microsoft, porque si fuera:"Por dinero, siempre decimal"?

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

Financial.IPmt y todos los otros métodos recibirían/​​retorno y no decimaldouble como es.

Ahora me pregunto si puedo usar estos métodos sin preocuparme por errores redondos?

¿Debo usar algunas otras bibliotecas para trabajar con las finanzas? En caso afirmativo, ¿podría indicarme algunas buenas (para el uso de C#)?

+1

Mi conjetura totalmente-not-a-VB-usuario sería que la biblioteca financiera probablemente maneja el almacenamiento correctamente internamente, pero yo no apostaría por ello. Debería verificar si el manejo interno es consistente o no antes de solo condenarlo en función del tipo de devolución. – Matchu

+18

Mi voto es booleano - usted tiene dinero o no ;-) – scunliffe

+1

Pasa lo mismo con VB y C# – Dryadwoods

Respuesta

3

Se puede utilizar esta clase:

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

Hola, ¿para qué sirve la variable Per? – cbp

+0

@cbp Consulte la función VB para [PPmt] (https://msdn.microsoft.com/en-us/library/microsoft.visualbasic.financial.ppmt.aspx), que coincide con la función 'PPmt' aquí (segundo función), que llama a 'IPmt'. –

10

Aquí hay una interesante discusión con respecto a exactamente este tema: http://www.vbforums.com/showthread.php?t=524101

Aproximadamente 1/3 del camino hacia abajo a alguien explica que utiliza doble ya que las funciones de VB.NET se llevaron a cabo a trabajar exactamente igual que VB6. VB6 no tiene un tipo decimal, por lo que utiliza el doble.

Por lo tanto, parece que si la precisión es importante, no debería usar estas funciones.

Las respuestas a this question tienen algunas alternativas prometedoras - simplemente ignorar la respuesta aceptada que sugiere el uso de la biblioteca VB.

La pregunta previamente vinculado ha sido borrado, así que aquí están algunas de las sugerencias que se refería a (nota: no he probado estos, tu caso es distinto)

+0

VB6 sí tiene un tipo de moneda, que es un Int64 con cuatro lugares decimales implícitos. –

+0

Decidí escribir mis propios métodos de finanzas con valores decimales. Reflector Red Gate's.Net como una herramienta útil: D – Dryadwoods

8

La regla de usar decimal-precio es muy útil porque la mayoría de las monedas tienen unidades decimales. Al usar la aritmética decimal, evitas introducir y acumular el error de redondeo.

Financial Class functions uso de punto flotante por varias razones:

  • Ellos no lo hacen internamente acumulan - que se basan en una forma cerrada/cálculo logarítmico exponencial, no iteración y suma sobre períodos.
  • Tienden a no usar o producir valores decimales exactos. Por ejemplo, una tasa de interés anual decimal exacta dividida por 12 pagos mensuales se convierte en un decimal periódico.
  • Están destinados principalmente a la toma de decisiones, y al final tienen poca aplicabilidad a la contabilidad real.

Pmt y el redondeo puede determinar el pago mensual nominal, pero una vez que se determina que la cantidad, la acumulación de equilibrio - los pagos realizados, tasas de interés aplicadas, etc. - sucede en decimal. Además, los pagos atrasados ​​o por adelantado, las vacaciones de pago y otras no uniformidades invalidarían la amortización proyectada provista por las funciones financieras.

Cuestiones relacionadas