[mono-vb] Implementation of Financial vb module

Rob.Tillie@Student.tUL.EDU Rob.Tillie@Student.tUL.EDU
Mon, 14 Jun 2004 20:14:59 +0200


This message is in MIME format. Since your mail reader does not understand
this format, some or all of this message may not be legible.

------_=_NextPart_000_01C4523B.80DC8420
Content-Type: text/plain

Here's a repost, I corrected all the formatting things and added the error
messages to VBUtils.txt.
No repost for the unit tests.

Could someone plz commit?

Greetz,
-- Rob.

> -----Original Message-----
> From: Andreas Nahr [mailto:ClassDevelopment@A-SoftTech.com]
> Sent: Monday, June 14, 2004 12:45 AM
> To: Rob.Tillie@Student.tUL.EDU; mono-vb@lists.ximian.com
> Subject: Re: [mono-vb] Implementation of Financial vb module
> 
> Hi,
> 
> I've just looked over your patch from the formatting point of view (some
> examples):
> 
> -namespace Microsoft.VisualBasic
> +namespace Microsoft.VisualBasic
> + <-- Line not needed
>  {
>   [StandardModule]
>   sealed public class Financial {
> @@ -19,32 +43,331 @@
>    private Financial() {} <-- Extend to three lines
> 
> +  public static System.Double DDB (System.Double Cost, System.Double
> Salvage, System.Double Life, System.Double Period,
> [System.Runtime.InteropServices.Optional]
> [System.ComponentModel.DefaultValue(2)] System.Double Factor)
> Should be:
> +  public static double DDB (double Cost, double Salvage, double Life,
> double Period, [Optional, DefaultValue (2)] double Factor)
> 
> throw new ArgumentException ("Argument 'Per' is not valid");
> Should be:
> throw new ArgumentException (Locale.GetText ("Invalid argument value."),
> "Per");
> 
> 
> Also Tab is correct for spacing, however at various places tabs and spaces
> are mixed, but only tabs should be used.
> 
> Andreas
> 
> ----- Original Message -----
> From: <Rob.Tillie@Student.tUL.EDU>
> To: <mono-vb@lists.ximian.com>
> Sent: Saturday, June 12, 2004 1:17 PM
> Subject: [mono-vb] Implementation of Financial vb module
> 
> 
> > Hello all,
> >
> > Because of the complexity of FileSystem, I implemented Financial first
> > together with unit tests, to get a feel for Mono and its formatting.
> >
> > It is largely copied from the MainSoft code, but I corrected a few
> > implementation differences with MS.NET.
> > Everything works like on MS.NET now.
> >
> > Because this is my first contribution, I would love to get some feedback
> on
> > what I have done wrong, especially concerning formatting.
> > I used the tab character now for tabs, couldn't figure out if I was
> supposed
> > to use tab character or spaces.
> >
> > The formatting of FileSystem is pretty screwed up, could someone fix
> this
> or
> > could I post a formatting patch?
> >
> > Greetz,
> > -- Rob.
> >
> >


------_=_NextPart_000_01C4523B.80DC8420
Content-Type: application/octet-stream;
	name="Financial.patch"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
	filename="Financial.patch"

Index: Financial.cs
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: =
/mono/mcs/class/Microsoft.VisualBasic/Microsoft.VisualBasic/Financial.cs=
,v
retrieving revision 1.4
diff -u -r1.4 Financial.cs
--- Financial.cs	31 May 2004 05:35:21 -0000	1.4
+++ Financial.cs	14 Jun 2004 18:11:08 -0000
@@ -3,14 +3,39 @@
 //
 // Author:
 //   Chris J Breisch (cjbreisch@altavista.net)=20
+//   Rob Tillie (Rob@flep-tech.nl)
 //
 // (C) 2002 Chris J Breisch
-//
+// (C) 2004 Rob Tillie
+// (C) 2002-2003 MainSoft
+ /*
+  * Copyright (c) 2002-2003 Mainsoft Corporation.
+  *
+  * Permission is hereby granted, free of charge, to any person =
obtaining a
+  * copy of this software and associated documentation files (the =
"Software"),
+  * to deal in the Software without restriction, including without =
limitation
+  * the rights to use, copy, modify, merge, publish, distribute, =
sublicense,
+  * and/or sell copies of the Software, and to permit persons to whom =
the
+  * Software is furnished to do so, subject to the following =
conditions:
+  *=20
+  * The above copyright notice and this permission notice shall be =
included in
+  * all copies or substantial portions of the Software.
+  *=20
+  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, =
EXPRESS OR
+  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF =
MERCHANTABILITY,
+  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT =
SHALL THE
+  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR =
OTHER
+  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, =
ARISING
+  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR =
OTHER
+  * DEALINGS IN THE SOFTWARE.
+  */
=20
 using System;
+using System.ComponentModel;
+using System.Runtime.InteropServices;
 using Microsoft.VisualBasic.CompilerServices;
=20
-namespace Microsoft.VisualBasic=20
+namespace Microsoft.VisualBasic=20
 {
 	[StandardModule]=20
 	sealed public class Financial {
@@ -19,32 +44,347 @@
 		private Financial() {} // prevent public default constructor
 		// Properties
 		// Methods
-		[MonoTODO]
-		public static System.Double DDB (System.Double Cost, System.Double =
Salvage, System.Double Life, System.Double Period, =
[System.Runtime.InteropServices.Optional] =
[System.ComponentModel.DefaultValue(2)] System.Double Factor) { throw =
new NotImplementedException (); }
-		[MonoTODO]
-		public static System.Double FV (System.Double Rate, System.Double =
NPer, System.Double Pmt, [System.Runtime.InteropServices.Optional] =
[System.ComponentModel.DefaultValue(0)] System.Double PV, =
[System.Runtime.InteropServices.Optional] =
[System.ComponentModel.DefaultValue(0)] Microsoft.VisualBasic.DueDate =
Due) { throw new NotImplementedException (); }
-		[MonoTODO]
-		public static System.Double IPmt (System.Double Rate, System.Double =
Per, System.Double NPer, System.Double PV, =
[System.Runtime.InteropServices.Optional] =
[System.ComponentModel.DefaultValue(0)] System.Double FV, =
[System.Runtime.InteropServices.Optional] =
[System.ComponentModel.DefaultValue(0)] Microsoft.VisualBasic.DueDate =
Due) { throw new NotImplementedException (); }
-		[MonoTODO]
-		public static System.Double IRR (ref System.Double[] ValueArray, =
[System.Runtime.InteropServices.Optional] =
[System.ComponentModel.DefaultValue(0.1)] System.Double Guess) { throw =
new NotImplementedException (); }
-		[MonoTODO]
-		public static System.Double MIRR (ref System.Double[] ValueArray, =
System.Double FinanceRate, System.Double ReinvestRate) { throw new =
NotImplementedException (); }
-		[MonoTODO]
-		public static System.Double NPer (System.Double Rate, System.Double =
Pmt, System.Double PV, [System.Runtime.InteropServices.Optional] =
[System.ComponentModel.DefaultValue(0)] System.Double FV, =
[System.Runtime.InteropServices.Optional] =
[System.ComponentModel.DefaultValue(0)] Microsoft.VisualBasic.DueDate =
Due) { throw new NotImplementedException (); }
-		[MonoTODO]
-		public static System.Double NPV (System.Double Rate, ref =
System.Double[] ValueArray) { throw new NotImplementedException (); }
-		[MonoTODO]
-		public static System.Double Pmt (System.Double Rate, System.Double =
NPer, System.Double PV, [System.Runtime.InteropServices.Optional] =
[System.ComponentModel.DefaultValue(0)] System.Double FV, =
[System.Runtime.InteropServices.Optional] =
[System.ComponentModel.DefaultValue(0)] Microsoft.VisualBasic.DueDate =
Due) { throw new NotImplementedException (); }
-		[MonoTODO]
-		public static System.Double PPmt (System.Double Rate, System.Double =
Per, System.Double NPer, System.Double PV, =
[System.Runtime.InteropServices.Optional] =
[System.ComponentModel.DefaultValue(0)] System.Double FV, =
[System.Runtime.InteropServices.Optional] =
[System.ComponentModel.DefaultValue(0)] Microsoft.VisualBasic.DueDate =
Due) { throw new NotImplementedException (); }
-		[MonoTODO]
-		public static System.Double PV (System.Double Rate, System.Double =
NPer, System.Double Pmt, [System.Runtime.InteropServices.Optional] =
[System.ComponentModel.DefaultValue(0)] System.Double FV, =
[System.Runtime.InteropServices.Optional] =
[System.ComponentModel.DefaultValue(0)] Microsoft.VisualBasic.DueDate =
Due) { throw new NotImplementedException (); }
-		[MonoTODO]
-		public static System.Double Rate (System.Double NPer, System.Double =
Pmt, System.Double PV, [System.Runtime.InteropServices.Optional] =
[System.ComponentModel.DefaultValue(0)] System.Double FV, =
[System.Runtime.InteropServices.Optional] =
[System.ComponentModel.DefaultValue(0)] Microsoft.VisualBasic.DueDate =
Due, [System.Runtime.InteropServices.Optional] =
[System.ComponentModel.DefaultValue(0.1)] System.Double Guess) { throw =
new NotImplementedException (); }
-		[MonoTODO]
-		public static System.Double SLN (System.Double Cost, System.Double =
Salvage, System.Double Life) { throw new NotImplementedException (); }
-		[MonoTODO]
-		public static System.Double SYD (System.Double Cost, System.Double =
Salvage, System.Double Life, System.Double Period) { throw new =
NotImplementedException (); }
+		public static double DDB (double Cost, double Salvage, double Life, =
double Period,=20
+					  [Optional, DefaultValue (2)] double Factor)
+		{=20
+			// LAMESPEC: MSDN says Life and Factor only throws exception if < =
0, but Implementation throws exception if <=3D 0
+			if (Cost < 0
+			    || Salvage < 0
+			    || Life <=3D 0
+			    || Period < 0
+			    || Factor <=3D 0
+			    || Period > Life)
+				throw new ArgumentException (Utils.GetResourceString =
("Argument_InvalidValue1", "Factor"));
+		=09
+			return (((Cost - Salvage) * Factor) / Life) * Period;
+		}
+	=09
+		public static double FV (double Rate, double NPer, double Pmt,=20
+					 [Optional, DefaultValue (0)] double PV,=20
+					 [Optional, DefaultValue (0)] DueDate Due)
+		{=20
+			Pmt =3D -Pmt;
+			PV =3D -PV;
+			double currentRate =3D Math.Pow (Rate + 1, NPer);
+			double sum =3D 0;
+		=09
+			if (Rate !=3D 0)
+				sum =3D Pmt * ((currentRate - 1) / Rate);
+			else
+				sum =3D Pmt * NPer;
+=09
+			if (Due =3D=3D DueDate.BegOfPeriod)
+				sum *=3D (1 + Rate);
+		=09
+			return PV * currentRate + sum;
+		}
+	=09
+		public static double IPmt (double Rate, double Per, double NPer, =
double PV,=20
+					   [Optional, DefaultValue (0)] double FV,=20
+					   [Optional, DefaultValue (0)] DueDate Due)
+		{=20
+			double totalFutureVal;
+			double totalPaymentValue;
+			double numberOfPeriods;
+		=09
+			if ((Per <=3D 0) || (Per >=3D (NPer + 1)))
+				throw new ArgumentException (Utils.GetResourceString =
("Argument_InvalidValue1", "Per"));
+			if ((Due =3D=3D DueDate.BegOfPeriod) && (Per =3D=3D 1))
+				return 0;
+		=09
+			totalPaymentValue =3D Pmt (Rate, NPer, PV, FV, Due);
+			if (Due =3D=3D DueDate.BegOfPeriod)
+				PV =3D (PV + totalPaymentValue);
+		=09
+			numberOfPeriods =3D Per - ((int)Due) - 1;
+			totalFutureVal =3D
+				Financial.FV (Rate, numberOfPeriods, totalPaymentValue, PV, =
DueDate.EndOfPeriod);
+		=09
+			return (totalFutureVal * Rate);
+		}
+	=09
+		public static double IRR (ref double[] ValueArray, [Optional, =
DefaultValue (0.1)] double Guess)=20
+		{=20
+			double origPV, updatedPV, updateGuess, tmp;
+			double rateDiff =3D 0.0;
+			double pvDiff =3D 0.0;
+			int length;
+		=09
+			// MS.NET 2.0 docs say that Guess may not be <=3D -1
+			if (Guess <=3D -1)       =20
+				throw new ArgumentException (Utils.GetResourceString =
("Argument_InvalidValue1", "Guess"));       =20
+			try {
+				length =3D ValueArray.GetLength(0);
+			}
+			catch {
+				throw new ArgumentException (Utils.GetResourceString =
("Argument_InvalidValue1", "ValueArray"));
+			}
+			if (length < 2)       =20
+			    throw new ArgumentException (Utils.GetResourceString =
("Argument_InvalidValue1", "ValueArray"));      =20
+		=09
+			origPV =3D NPV (Guess, ref ValueArray);
+			updateGuess =3D (origPV > 0) ? Guess + 0.00001 : Guess - 0.00001;   =

+		=09
+			if (updateGuess < -1)
+			    throw new ArgumentException (Utils.GetResourceString =
("Argument_InvalidValue1", "Rate"));
+		=09
+			rateDiff =3D  updateGuess - Guess;      =20
+			updatedPV =3D NPV (updateGuess, ref ValueArray);
+			pvDiff =3D updatedPV - origPV;
+			for (int i =3D 0; i < 20; i++) {
+				Guess =3D (updateGuess > Guess) ? (Guess - 0.00001) : (Guess + =
0.00001);
+				origPV =3D NPV (Guess, ref ValueArray);
+				rateDiff =3D  updateGuess - Guess;
+				pvDiff =3D updatedPV - origPV;  =20
+				if (pvDiff =3D=3D 0)
+					throw new ArgumentException (Utils.GetResourceString =
("Argument_InvalidValue"));
+				Guess =3D updateGuess - (rateDiff * updatedPV / pvDiff);
+				if (Guess < -1)
+				Guess =3D -1;
+				origPV =3D NPV (Guess, ref ValueArray);
+				if ((Math.Abs (origPV) < 0.0000001) && (Math.Abs (rateDiff) < =
0.00001))
+					return Guess;
+			=09
+				tmp =3D Guess;
+				Guess =3D updateGuess;
+				updateGuess =3D tmp;
+				tmp =3D origPV;
+				origPV =3D updatedPV;
+				updatedPV =3D tmp;
+			}
+			double origPVAbs =3D Math.Abs (origPV);
+			double updatedPVAbs =3D Math.Abs (updatedPV);
+			if ((origPVAbs < 0.0000001) && (updatedPVAbs < 0.0000001))
+			    return (origPVAbs < updatedPVAbs) ? Guess : updateGuess;
+			else if (origPVAbs < 0.0000001)
+			    return  Guess;
+			else if (updatedPVAbs < 0.0000001)
+			    return updateGuess;
+			else               =20
+			    throw new ArgumentException(Utils.GetResourceString =
("Argument_InvalidValue"));
+		}
+	=09
+		public static double MIRR (ref double[] ValueArray, double =
FinanceRate, double ReinvestRate)
+		{=20
+			double [] array =3D ValueArray;
+			double loansVal =3D 0;
+			double assetsVal =3D 0;
+			double currentLoanRate =3D 1;
+			double currentAssetsRate =3D 1;
+			double totalInterestRate =3D 0;
+			int arrayLength =3D 0;
+			if (array.Rank !=3D 1)
+				throw new ArgumentException (Utils.GetResourceString =
("Argument_RankEQOne1", "ValueArray"));
+			else if (FinanceRate =3D=3D -1)
+				throw new ArgumentException (Utils.GetResourceString =
("Argument_InvalidValue1", "FinanceRate"));
+			else if (ReinvestRate =3D=3D -1)
+				throw new ArgumentException (Utils.GetResourceString =
("Argument_InvalidValue1", "ReinvestRate"));
+		=09
+			arrayLength =3D array.Length;
+			if (arrayLength < 2)
+				throw new ArgumentException (Utils.GetResourceString =
("Argument_InvalidValue1", "ValueArray"));
+		=09
+			for (int i =3D 0; i < arrayLength; i++) {
+				currentLoanRate *=3D (1 + FinanceRate);
+				currentAssetsRate *=3D (1 + ReinvestRate);
+				if (array [i] < 0)
+				loansVal +=3D (array [i] / currentLoanRate);
+				else if (array [i] > 0)
+				assetsVal +=3D (array [i] / currentAssetsRate);
+			}
+		=09
+			if (loansVal =3D=3D 0)
+				throw new DivideByZeroException (Utils.GetResourceString =
("Financial_CalcDivByZero"));
+		=09
+			totalInterestRate =3D
+				((-assetsVal * Math.Pow (ReinvestRate + 1, arrayLength))
+				/ (loansVal * (FinanceRate + 1)));
+			if (totalInterestRate < 0)
+				throw new ArgumentException (Utils.GetResourceString =
("Argument_InvalidValue"));
+		=09
+			return (Math.Pow (totalInterestRate, 1 / (double) (arrayLength - =
1))) - 1;
+		}
+	=09
+		public static double NPer (double Rate, double Pmt, double PV,=20
+					   [Optional, DefaultValue (0)] double FV,=20
+					   [Optional, DefaultValue (0)] DueDate Due)
+		{=20
+			double totalIncomeFromFlow, sumOfPvAndPayment, =
currentValueOfPvAndPayment;
+			if (Rate =3D=3D 0 && Pmt =3D=3D 0)
+				throw new ArgumentException (Utils.GetResourceString =
("Argument_InvalidValue1", "Pmt"));
+			else if (Rate =3D=3D 0)
+				return (- (PV + FV) / Pmt);
+			// MainSoft had Rate < -1, but MS.NET 2.0 Doc says Rate should not =
be <=3D -1
+			else if (Rate <=3D -1)
+				throw new ArgumentException(Utils.GetResourceString =
("Argument_InvalidValue1", "Rate"));
+			totalIncomeFromFlow =3D (Pmt / Rate);
+			if (Due =3D=3D DueDate.BegOfPeriod)
+			totalIncomeFromFlow *=3D (1 + Rate);
+		=09
+			sumOfPvAndPayment =3D (-FV + totalIncomeFromFlow);
+			currentValueOfPvAndPayment =3D (PV + totalIncomeFromFlow);
+			if ((sumOfPvAndPayment < 0) && (currentValueOfPvAndPayment < 0)) {
+				sumOfPvAndPayment =3D -sumOfPvAndPayment;
+				currentValueOfPvAndPayment =3D -currentValueOfPvAndPayment;
+			}
+			else if ((sumOfPvAndPayment <=3D 0) || (currentValueOfPvAndPayment =
< 0))
+				throw new ArgumentException (Utils.GetResourceString =
("Financial_CannotCalculateNPer"));
+		=09
+			double totalInterestRate =3D sumOfPvAndPayment / =
currentValueOfPvAndPayment;
+			return Math.Log (totalInterestRate) / Math.Log (Rate + 1);
+		}
+	=09
+		public static double NPV (double Rate, ref double[] ValueArray)=20
+		{=20
+			if (ValueArray =3D=3D null)
+				throw new ArgumentException (Utils.GetResourceString =
("Argument_InvalidNullValue1", "ValueArray"));
+		=09
+			double [] arr =3D ValueArray;
+			if (arr.Rank !=3D 1)
+				throw new ArgumentException (Utils.GetResourceString =
("Argument_RankEQOne1", "ValueArray"));
+			if (Rate =3D=3D -1)
+				throw new ArgumentException (Utils.GetResourceString =
("Argument_InvalidValue1", "Rate"));
+			int length =3D arr.Length;
+			if (length < 0)
+				throw new ArgumentException (Utils.GetResourceString =
("Argument_InvalidValue1", "ValueArray"));
+		=09
+			double currentValue =3D 0;
+			double currentRate =3D 1;
+			double sum =3D 0;
+			for (int index =3D 0; index < length; index++) {
+				currentValue =3D arr [index];
+				currentRate *=3D (1 + Rate);
+				sum +=3D (currentValue / currentRate);
+			}
+			return sum;
+		}
+	=09
+		public static double Pmt (double Rate, double NPer, double PV,=20
+					  [Optional, DefaultValue (0)] double FV,=20
+					  [Optional, DefaultValue (0)] DueDate Due)
+		{=20
+			PV =3D -PV;
+			FV =3D -FV;
+			if (NPer =3D=3D 0)
+				throw new ArgumentException (Utils.GetResourceString =
("Argument_InvalidValue1", "NPer"));
+		=09
+			double totalFutureVal =3D 0;
+			double geometricSum =3D 0;=20
+			if (Rate =3D=3D 0) {
+				totalFutureVal =3D FV + PV;
+				geometricSum =3D NPer;
+			}
+			else if (Due =3D=3D DueDate.EndOfPeriod) {
+				double totalRate =3D Math.Pow (Rate + 1, NPer);
+				totalFutureVal =3D FV + PV * totalRate;
+				geometricSum =3D (totalRate - 1) / Rate;
+			}
+			else if (Due =3D=3D DueDate.BegOfPeriod) {
+				double totalRate =3D Math.Pow (Rate + 1, NPer);
+				totalFutureVal =3D FV + PV * totalRate;
+				geometricSum =3D ((1 + Rate) * (totalRate - 1)) / Rate;       =20
+			}
+			return (totalFutureVal) / geometricSum;=20
+		}
+	=09
+		public static double PPmt (double Rate, double Per, double NPer, =
double PV,=20
+					   [Optional, DefaultValue (0)] double FV,=20
+					   [Optional, DefaultValue (0)] DueDate Due)
+		{=20
+			if ((Per <=3D 0) || (Per >=3D (NPer + 1)))
+				throw new ArgumentException(Utils.GetResourceString =
("PPMT_PerGT0AndLTNPer", "Per"));
+			double interestPayment =3D IPmt (Rate, Per, NPer, PV, FV, Due);
+			double totalPayment =3D Pmt (Rate, NPer, PV, FV, Due);
+			return (totalPayment - interestPayment);
+		}
+	=09
+		public static double PV (double Rate, double NPer, double Pmt,=20
+					 [Optional, DefaultValue (0)] double FV,=20
+					 [Optional, DefaultValue (0)] DueDate Due)
+		{=20
+			Pmt =3D -Pmt;
+			FV =3D -FV;
+			double currentRate =3D 1;
+			double sum =3D 0;
+			for (int index =3D 1; index <=3D NPer; index++) {
+				currentRate *=3D (1 + Rate);
+				sum +=3D (Pmt / currentRate);
+			}
+		=09
+			if (Due =3D=3D DueDate.BegOfPeriod)
+				sum *=3D (1 + Rate);
+			return sum + FV / currentRate;   =20
+		}
+	=09
+		public static double Rate (double NPer, double Pmt, double PV,=20
+					   [Optional, DefaultValue (0)] double FV,=20
+					   [Optional, DefaultValue (0)] DueDate Due,=20
+					   [Optional, DefaultValue (0.1)] double Guess)
+		{=20
+			double updatedGuess, tmp, origFv, updatedFv;
+			double rateDiff =3D 0.0;
+			double fvDiff =3D 0.0;
+		=09
+			if (NPer < 0)
+				throw new ArgumentException (Utils.GetResourceString =
("Rate_NPerMustBeGTZero"));
+			origFv =3D -Financial.FV (Guess, NPer, Pmt, PV, Due) + FV;
+			updatedGuess =3D (origFv > 0) ? (Guess / 2) : (Guess * 2);
+			rateDiff =3D updatedGuess - Guess;
+			updatedFv =3D -Financial.FV (updatedGuess, NPer, Pmt, PV, Due) + =
FV;
+			fvDiff =3D updatedFv - origFv;
+			for (int i =3D 0; i < 20; i++) {
+				Guess +=3D (updatedGuess > Guess) ? -0.00001 : 0.00001;
+				origFv =3D -Financial.FV (Guess, NPer, Pmt, PV, Due) + FV;
+				rateDiff =3D updatedGuess - Guess;
+				fvDiff =3D updatedFv - origFv;
+				if (fvDiff =3D=3D 0)
+					throw new ArgumentException (Utils.GetResourceString =
("Financial_CalcDivByZero"));
+				Guess =3D updatedGuess - (rateDiff * updatedFv / fvDiff);
+				origFv =3D -Financial.FV (Guess, NPer, Pmt, PV, Due) + FV;
+				if (Math.Abs (origFv) < 0.0000001)
+					return Guess;
+				tmp =3D Guess;
+				Guess =3D updatedGuess;
+				updatedGuess =3D tmp;
+				tmp =3D origFv;
+				origFv =3D updatedFv;
+				updatedFv =3D tmp;
+			}
+			double origFVAbs =3D Math.Abs (origFv);
+			double updatedFVAbs =3D Math.Abs (updatedFv);
+			if ((origFVAbs < 0.0000001) && (updatedFVAbs < 0.0000001))
+				return (origFVAbs < updatedFVAbs) ? Guess : updatedGuess;
+			else if (origFVAbs < 0.0000001)
+				return Guess;
+			else if (updatedFVAbs < 0.0000001)
+				return updatedGuess;
+			else
+				throw new ArgumentException (Utils.GetResourceString =
("Financial_CannotCalculateRate"));=20
+		}
+	=09
+		public static double SLN (double Cost, double Salvage, double Life)
+		{=20
+			if (Life =3D=3D 0)
+				throw new ArgumentException (Utils.GetResourceString =
("Financial_LifeNEZero"));
+		=09
+			return (Cost - Salvage) / Life;
+		}
+	=09
+		public static double SYD (double Cost, double Salvage, double Life, =
double Period)=20
+		{=20
+			if (Period <=3D 0)
+				throw new ArgumentException =
(Utils.GetResourceString("Financial_ArgGTZero1", "Period"));
+			else if (Salvage < 0)
+				throw new ArgumentException =
(Utils.GetResourceString("Financial_ArgGEZero1", "Salvage"));
+			else if (Period > Life)
+				throw new ArgumentException =
(Utils.GetResourceString("Financial_PeriodLELife"));
+		=09
+			double depreciation =3D  (Cost - Salvage);
+			double sumOfDigits =3D (Life + 1) * Life / 2;
+			double currentPeriodPart =3D Life + 1 - Period ;=20
+		=09
+			return depreciation * currentPeriodPart / sumOfDigits;
+		}
 		// Events
-	};
+	}
 }

------_=_NextPart_000_01C4523B.80DC8420
Content-Type: application/octet-stream;
	name="VBUtils.txt.patch"
Content-Disposition: attachment;
	filename="VBUtils.txt.patch"

Index: VBUtils.txt
===================================================================
RCS file: /mono/mcs/class/Microsoft.VisualBasic/Microsoft.VisualBasic/VBUtils.txt,v
retrieving revision 1.1
diff -u -r1.1 VBUtils.txt
--- VBUtils.txt	7 Jun 2004 08:44:52 -0000	1.1
+++ VBUtils.txt	14 Jun 2004 18:04:04 -0000
@@ -120,16 +120,16 @@
 UseFilePutObject = FIXME: UseFilePutObject
 
 # Errors in Financial.java
-Argument_RankEQOne1 = FIXME: Argument_RankEQOne1 |1
-Financial_CalcDivByZero = FIXME: Financial_CalcDivByZero
-Financial_CannotCalculateNPer = FIXME: Financial_CannotCalculateNPer
-PPMT_PerGT0AndLTNPer = FIXME: PPMT_PerGT0AndLTNPer |1
-Rate_NPerMustBeGTZero = FIXME: Rate_NPerMustBeGTZero
-Financial_CannotCalculateRate = FIXME: Financial_CannotCalculateRate
-Financial_LifeNEZero = FIXME: Financial_LifeNEZero
-Financial_ArgGTZero1 = FIXME: Financial_ArgGTZero1 |1
-Financial_ArgGEZero1 = FIXME: Financial_ArgGEZero1 |1
-Financial_PeriodLELife = FIXME: Financial_PeriodLELife
+Argument_RankEQOne1 = Rank of |1 does not equal 1.
+Financial_CalcDivByZero = Division by zero has occurred.
+Financial_CannotCalculateNPer = Cannot calculate NPer.
+PPMT_PerGT0AndLTNPer = |1 value invalid, it must be greater than 1 and smaller than NPer.
+Rate_NPerMustBeGTZero = Rate must be less than or equal to 0.
+Financial_CannotCalculateRate = Cannot calculate Rate.
+Financial_LifeNEZero = Life cannot be zero.
+Financial_ArgGTZero1 = |1 must be greater than 0.
+Financial_ArgGEZero1 = |1 must be greater than or equal to 0.
+Financial_PeriodLELife = Period must be greater than Life.
 
 # Errors in FlowControl.java
 ForLoop_CommonType3 = FIXME: ForLoop_CommonType3 |1 |2 |3

------_=_NextPart_000_01C4523B.80DC8420--