2 * Copyright (C) 1987-2008 Sun Microsystems, Inc. All Rights Reserved.
3 * Copyright (C) 2008-2011 Robert Ancell
5 * This program is free software: you can redistribute it and/or modify it under
6 * the terms of the GNU General Public License as published by the Free Software
7 * Foundation, either version 2 of the License, or (at your option) any later
8 * version. See http://www.gnu.org/copyleft/gpl.html the full text of the
12 #include <glib/gi18n.h>
14 #include "financial.h"
18 calc_ctrm(MathEquation
*equation
, MPNumber
*t
, MPNumber
*pint
, MPNumber
*fv
, MPNumber
*pv
)
21 /* Cterm - pint (periodic interest rate).
25 * RESULT = log(fv / pv) / log(1 + pint)
27 MPNumber MP1
, MP2
, MP3
, MP4
;
29 mp_divide(fv
, pv
, &MP1
);
31 mp_add_integer(pint
, 1, &MP3
);
33 mp_divide(&MP2
, &MP4
, t
);
38 calc_ddb(MathEquation
*equation
, MPNumber
*t
, MPNumber
*cost
, MPNumber
*life
, MPNumber
*period
)
41 /* Ddb - cost (amount paid for asset).
42 * life (useful life of the asset).
43 * period (time period for depreciation allowance).
46 * for (i = 0; i < life; i++)
48 * VAL = ((cost - bv) * 2) / life
57 MPNumber MPbv
, MP1
, MP2
;
59 mp_set_from_integer(0, &MPbv
);
60 len
= mp_cast_to_int(period
);
61 for (i
= 0; i
< len
; i
++) {
62 mp_subtract(cost
, &MPbv
, &MP1
);
63 mp_multiply_integer(&MP1
, 2, &MP2
);
64 mp_divide(&MP2
, life
, t
);
65 mp_set_from_mp(&MPbv
, &MP1
);
66 mp_add(&MP1
, t
, &MPbv
); /* TODO: why result is MPbv, for next loop? */
70 math_equation_set_status (equation
, _("Error: the number of periods must be positive"));
71 mp_set_from_integer(0, t
);
77 calc_fv(MathEquation
*equation
, MPNumber
*t
, MPNumber
*pmt
, MPNumber
*pint
, MPNumber
*n
)
80 /* Fv - pmt (periodic payment).
81 * pint (periodic interest rate).
82 * n (number of periods).
84 * RESULT = pmt * (pow(1 + pint, n) - 1) / pint
87 MPNumber MP1
, MP2
, MP3
, MP4
;
89 mp_add_integer(pint
, 1, &MP1
);
90 mp_xpowy(&MP1
, n
, &MP2
);
91 mp_add_integer(&MP2
, -1, &MP3
);
92 mp_multiply(pmt
, &MP3
, &MP4
);
93 mp_divide(&MP4
, pint
, t
);
98 calc_gpm(MathEquation
*equation
, MPNumber
*t
, MPNumber
*cost
, MPNumber
*margin
)
101 /* Gpm - cost (cost of sale).
102 * margin (gross profit margin.
104 * RESULT = cost / (1 - margin)
109 mp_set_from_integer(1, &MP1
);
110 mp_subtract(&MP1
, margin
, &MP2
);
111 mp_divide(cost
, &MP2
, t
);
116 calc_pmt(MathEquation
*equation
, MPNumber
*t
, MPNumber
*prin
, MPNumber
*pint
, MPNumber
*n
)
119 /* Pmt - prin (principal).
120 * pint (periodic interest rate).
123 * RESULT = prin * (pint / (1 - pow(pint + 1, -1 * n)))
126 MPNumber MP1
, MP2
, MP3
, MP4
;
128 mp_add_integer(pint
, 1, &MP1
);
129 mp_multiply_integer(n
, -1, &MP2
);
130 mp_xpowy(&MP1
, &MP2
, &MP3
);
131 mp_multiply_integer(&MP3
, -1, &MP4
);
132 mp_add_integer(&MP4
, 1, &MP1
);
133 mp_divide(pint
, &MP1
, &MP2
);
134 mp_multiply(prin
, &MP2
, t
);
139 calc_pv(MathEquation
*equation
, MPNumber
*t
, MPNumber
*pmt
, MPNumber
*pint
, MPNumber
*n
)
142 /* Pv - pmt (periodic payment).
143 * pint (periodic interest rate).
146 * RESULT = pmt * (1 - pow(1 + pint, -1 * n)) / pint
149 MPNumber MP1
, MP2
, MP3
, MP4
;
151 mp_add_integer(pint
, 1, &MP1
);
152 mp_multiply_integer(n
, -1, &MP2
);
153 mp_xpowy(&MP1
, &MP2
, &MP3
);
154 mp_multiply_integer(&MP3
, -1, &MP4
);
155 mp_add_integer(&MP4
, 1, &MP1
);
156 mp_divide(&MP1
, pint
, &MP2
);
157 mp_multiply(pmt
, &MP2
, t
);
162 calc_rate(MathEquation
*equation
, MPNumber
*t
, MPNumber
*fv
, MPNumber
*pv
, MPNumber
*n
)
165 /* Rate - fv (future value).
166 * pv (present value).
169 * RESULT = pow(fv / pv, 1 / n) - 1
172 MPNumber MP1
, MP2
, MP3
, MP4
;
174 mp_divide(fv
, pv
, &MP1
);
175 mp_set_from_integer(1, &MP2
);
176 mp_divide(&MP2
, n
, &MP3
);
177 mp_xpowy(&MP1
, &MP3
, &MP4
);
178 mp_add_integer(&MP4
, -1, t
);
183 calc_sln(MathEquation
*equation
, MPNumber
*t
, MPNumber
*cost
, MPNumber
*salvage
, MPNumber
*life
)
186 /* Sln - cost (cost of the asset).
187 * salvage (salvage value of the asset).
188 * life (useful life of the asset).
190 * RESULT = (cost - salvage) / life
194 mp_subtract(cost
, salvage
, &MP1
);
195 mp_divide(&MP1
, life
, t
);
200 calc_syd(MathEquation
*equation
, MPNumber
*t
, MPNumber
*cost
, MPNumber
*salvage
, MPNumber
*life
, MPNumber
*period
)
203 /* Syd - cost (cost of the asset).
204 * salvage (salvage value of the asset).
205 * life (useful life of the asset).
206 * period (period for which depreciation is computed).
208 * RESULT = (cost - salvage) * (life - period + 1) /
209 * (life * (life + 1)) / 2
212 MPNumber MP1
, MP2
, MP3
, MP4
;
214 mp_subtract(life
, period
, &MP2
);
215 mp_add_integer(&MP2
, 1, &MP3
);
216 mp_add_integer(life
, 1, &MP2
);
217 mp_multiply(life
, &MP2
, &MP4
);
218 mp_set_from_integer(2, &MP2
);
219 mp_divide(&MP4
, &MP2
, &MP1
);
220 mp_divide(&MP3
, &MP1
, &MP2
);
221 mp_subtract(cost
, salvage
, &MP1
);
222 mp_multiply(&MP1
, &MP2
, t
);
227 calc_term(MathEquation
*equation
, MPNumber
*t
, MPNumber
*pmt
, MPNumber
*fv
, MPNumber
*pint
)
230 /* Term - pmt (periodic payment).
232 * pint (periodic interest rate).
234 * RESULT = log(1 + (fv * pint / pmt)) / log(1 + pint)
237 MPNumber MP1
, MP2
, MP3
, MP4
;
239 mp_add_integer(pint
, 1, &MP1
);
241 mp_multiply(fv
, pint
, &MP1
);
242 mp_divide(&MP1
, pmt
, &MP3
);
243 mp_add_integer(&MP3
, 1, &MP4
);
245 mp_divide(&MP1
, &MP2
, t
);
250 do_finc_expression(MathEquation
*equation
, int function
, MPNumber
*arg1
, MPNumber
*arg2
, MPNumber
*arg3
, MPNumber
*arg4
)
254 case FINC_CTRM_DIALOG
:
255 calc_ctrm(equation
, &result
, arg1
, arg2
, arg3
);
257 case FINC_DDB_DIALOG
:
258 calc_ddb(equation
, &result
, arg1
, arg2
, arg3
);
261 calc_fv(equation
, &result
, arg1
, arg2
, arg3
);
263 case FINC_GPM_DIALOG
:
264 calc_gpm(equation
, &result
, arg1
, arg2
);
266 case FINC_PMT_DIALOG
:
267 calc_pmt(equation
, &result
, arg1
, arg2
, arg3
);
270 calc_pv(equation
, &result
, arg1
, arg2
, arg3
);
272 case FINC_RATE_DIALOG
:
273 calc_rate(equation
, &result
, arg1
, arg2
, arg3
);
275 case FINC_SLN_DIALOG
:
276 calc_sln(equation
, &result
, arg1
, arg2
, arg3
);
278 case FINC_SYD_DIALOG
:
279 calc_syd(equation
, &result
, arg1
, arg2
, arg3
, arg4
);
281 case FINC_TERM_DIALOG
:
282 calc_term(equation
, &result
, arg1
, arg2
, arg3
);
285 math_equation_set_number(equation
, &result
);