1 /* Copyright (c) 1987-2008 Sun Microsystems, Inc. All Rights Reserved.
2 * Copyright (c) 2008-2009 Robert Ancell
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2, or (at your option)
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20 #include <glib/gi18n.h>
22 #include "financial.h"
26 calc_ctrm(MathEquation
*equation
, MPNumber
*t
, MPNumber
*pint
, MPNumber
*fv
, MPNumber
*pv
)
29 /* Cterm - pint (periodic interest rate).
33 * RESULT = log(fv / pv) / log(1 + pint)
35 MPNumber MP1
, MP2
, MP3
, MP4
;
37 mp_divide(fv
, pv
, &MP1
);
39 mp_add_integer(pint
, 1, &MP3
);
41 mp_divide(&MP2
, &MP4
, t
);
46 calc_ddb(MathEquation
*equation
, MPNumber
*t
, MPNumber
*cost
, MPNumber
*life
, MPNumber
*period
)
49 /* Ddb - cost (amount paid for asset).
50 * life (useful life of the asset).
51 * period (time period for depreciation allowance).
54 * for (i = 0; i < life; i++)
56 * VAL = ((cost - bv) * 2) / life
65 MPNumber MPbv
, MP1
, MP2
;
67 mp_set_from_integer(0, &MPbv
);
68 len
= mp_cast_to_int(period
);
69 for (i
= 0; i
< len
; i
++) {
70 mp_subtract(cost
, &MPbv
, &MP1
);
71 mp_multiply_integer(&MP1
, 2, &MP2
);
72 mp_divide(&MP2
, life
, t
);
73 mp_set_from_mp(&MPbv
, &MP1
);
74 mp_add(&MP1
, t
, &MPbv
); /* TODO: why result is MPbv, for next loop? */
78 math_equation_set_status (equation
, ("Error: the number of periods must be positive"));
79 mp_set_from_integer(0, t
);
85 calc_fv(MathEquation
*equation
, MPNumber
*t
, MPNumber
*pmt
, MPNumber
*pint
, MPNumber
*n
)
88 /* Fv - pmt (periodic payment).
89 * pint (periodic interest rate).
90 * n (number of periods).
92 * RESULT = pmt * (pow(1 + pint, n) - 1) / pint
95 MPNumber MP1
, MP2
, MP3
, MP4
;
97 mp_add_integer(pint
, 1, &MP1
);
98 mp_xpowy(&MP1
, n
, &MP2
);
99 mp_add_integer(&MP2
, -1, &MP3
);
100 mp_multiply(pmt
, &MP3
, &MP4
);
101 mp_divide(&MP4
, pint
, t
);
106 calc_gpm(MathEquation
*equation
, MPNumber
*t
, MPNumber
*cost
, MPNumber
*margin
)
109 /* Gpm - cost (cost of sale).
110 * margin (gross profit margin.
112 * RESULT = cost / (1 - margin)
117 mp_set_from_integer(1, &MP1
);
118 mp_subtract(&MP1
, margin
, &MP2
);
119 mp_divide(cost
, &MP2
, t
);
124 calc_pmt(MathEquation
*equation
, MPNumber
*t
, MPNumber
*prin
, MPNumber
*pint
, MPNumber
*n
)
127 /* Pmt - prin (principal).
128 * pint (periodic interest rate).
131 * RESULT = prin * (pint / (1 - pow(pint + 1, -1 * n)))
134 MPNumber MP1
, MP2
, MP3
, MP4
;
136 mp_add_integer(pint
, 1, &MP1
);
137 mp_multiply_integer(n
, -1, &MP2
);
138 mp_xpowy(&MP1
, &MP2
, &MP3
);
139 mp_multiply_integer(&MP3
, -1, &MP4
);
140 mp_add_integer(&MP4
, 1, &MP1
);
141 mp_divide(pint
, &MP1
, &MP2
);
142 mp_multiply(prin
, &MP2
, t
);
147 calc_pv(MathEquation
*equation
, MPNumber
*t
, MPNumber
*pmt
, MPNumber
*pint
, MPNumber
*n
)
150 /* Pv - pmt (periodic payment).
151 * pint (periodic interest rate).
154 * RESULT = pmt * (1 - pow(1 + pint, -1 * n)) / pint
157 MPNumber MP1
, MP2
, MP3
, MP4
;
159 mp_add_integer(pint
, 1, &MP1
);
160 mp_multiply_integer(n
, -1, &MP2
);
161 mp_xpowy(&MP1
, &MP2
, &MP3
);
162 mp_multiply_integer(&MP3
, -1, &MP4
);
163 mp_add_integer(&MP4
, 1, &MP1
);
164 mp_divide(&MP1
, pint
, &MP2
);
165 mp_multiply(pmt
, &MP2
, t
);
170 calc_rate(MathEquation
*equation
, MPNumber
*t
, MPNumber
*fv
, MPNumber
*pv
, MPNumber
*n
)
173 /* Rate - fv (future value).
174 * pv (present value).
177 * RESULT = pow(fv / pv, 1 / n) - 1
180 MPNumber MP1
, MP2
, MP3
, MP4
;
182 mp_divide(fv
, pv
, &MP1
);
183 mp_set_from_integer(1, &MP2
);
184 mp_divide(&MP2
, n
, &MP3
);
185 mp_xpowy(&MP1
, &MP3
, &MP4
);
186 mp_add_integer(&MP4
, -1, t
);
191 calc_sln(MathEquation
*equation
, MPNumber
*t
, MPNumber
*cost
, MPNumber
*salvage
, MPNumber
*life
)
194 /* Sln - cost (cost of the asset).
195 * salvage (salvage value of the asset).
196 * life (useful life of the asset).
198 * RESULT = (cost - salvage) / life
202 mp_subtract(cost
, salvage
, &MP1
);
203 mp_divide(&MP1
, life
, t
);
208 calc_syd(MathEquation
*equation
, MPNumber
*t
, MPNumber
*cost
, MPNumber
*salvage
, MPNumber
*life
, MPNumber
*period
)
211 /* Syd - cost (cost of the asset).
212 * salvage (salvage value of the asset).
213 * life (useful life of the asset).
214 * period (period for which depreciation is computed).
216 * RESULT = (cost - salvage) * (life - period + 1) /
217 * (life * (life + 1)) / 2
220 MPNumber MP1
, MP2
, MP3
, MP4
;
222 mp_subtract(life
, period
, &MP2
);
223 mp_add_integer(&MP2
, 1, &MP3
);
224 mp_add_integer(life
, 1, &MP2
);
225 mp_multiply(life
, &MP2
, &MP4
);
226 mp_set_from_integer(2, &MP2
);
227 mp_divide(&MP4
, &MP2
, &MP1
);
228 mp_divide(&MP3
, &MP1
, &MP2
);
229 mp_subtract(cost
, salvage
, &MP1
);
230 mp_multiply(&MP1
, &MP2
, t
);
235 calc_term(MathEquation
*equation
, MPNumber
*t
, MPNumber
*pmt
, MPNumber
*fv
, MPNumber
*pint
)
238 /* Term - pmt (periodic payment).
240 * pint (periodic interest rate).
242 * RESULT = log(1 + (fv * pint / pmt)) / log(1 + pint)
245 MPNumber MP1
, MP2
, MP3
, MP4
;
247 mp_add_integer(pint
, 1, &MP1
);
249 mp_multiply(fv
, pint
, &MP1
);
250 mp_divide(&MP1
, pmt
, &MP3
);
251 mp_add_integer(&MP3
, 1, &MP4
);
253 mp_divide(&MP1
, &MP2
, t
);
258 do_finc_expression(MathEquation
*equation
, int function
, MPNumber
*arg1
, MPNumber
*arg2
, MPNumber
*arg3
, MPNumber
*arg4
)
262 case FINC_CTRM_DIALOG
:
263 calc_ctrm(equation
, &result
, arg1
, arg2
, arg3
);
265 case FINC_DDB_DIALOG
:
266 calc_ddb(equation
, &result
, arg1
, arg2
, arg3
);
269 calc_fv(equation
, &result
, arg1
, arg2
, arg3
);
271 case FINC_GPM_DIALOG
:
272 calc_gpm(equation
, &result
, arg1
, arg2
);
274 case FINC_PMT_DIALOG
:
275 calc_pmt(equation
, &result
, arg1
, arg2
, arg3
);
278 calc_pv(equation
, &result
, arg1
, arg2
, arg3
);
280 case FINC_RATE_DIALOG
:
281 calc_rate(equation
, &result
, arg1
, arg2
, arg3
);
283 case FINC_SLN_DIALOG
:
284 calc_sln(equation
, &result
, arg1
, arg2
, arg3
);
286 case FINC_SYD_DIALOG
:
287 calc_syd(equation
, &result
, arg1
, arg2
, arg3
, arg4
);
289 case FINC_TERM_DIALOG
:
290 calc_term(equation
, &result
, arg1
, arg2
, arg3
);
293 math_equation_set_number(equation
, &result
);