Updated Danish translation
[gcalctool.git] / src / financial.c
blob29850b0a67f83adb62e96516b5e152e85509dfa1
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)
7 * any later version.
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
17 * 02111-1307, USA.
20 #include "financial.h"
21 #include "calctool.h"
22 #include "mp.h"
24 #include <libintl.h>
26 void
27 calc_ctrm(MPNumber *t, MPNumber *pint, MPNumber *fv, MPNumber *pv)
30 /* Cterm - pint (periodic interest rate).
31 * fv (future value).
32 * pv (present value).
34 * RESULT = log(fv / pv) / log(1 + pint)
36 MPNumber MP1, MP2, MP3, MP4;
38 mp_divide(fv, pv, &MP1);
39 mp_ln(&MP1, &MP2);
40 mp_add_integer(pint, 1, &MP3);
41 mp_ln(&MP3, &MP4);
42 mp_divide(&MP2, &MP4, t);
46 void
47 calc_ddb(MPNumber *t, MPNumber *cost, MPNumber *life, MPNumber *period)
50 /* Ddb - cost (amount paid for asset).
51 * life (useful life of the asset).
52 * period (time period for depreciation allowance).
54 * bv = 0.0;
55 * for (i = 0; i < life; i++)
56 * {
57 * VAL = ((cost - bv) * 2) / life
58 * bv += VAL
59 * }
60 * RESULT = VAL
64 int i;
65 int len;
66 MPNumber MPbv, MP1, MP2;
68 mp_set_from_integer(0, &MPbv);
69 len = mp_cast_to_int(period);
70 for (i = 0; i < len; i++) {
71 mp_subtract(cost, &MPbv, &MP1);
72 mp_multiply_integer(&MP1, 2, &MP2);
73 mp_divide(&MP2, life, t);
74 mp_set_from_mp(&MPbv, &MP1);
75 mp_add(&MP1, t, &MPbv); /* TODO: why result is MPbv, for next loop? */
78 if (len >= 0) {
79 display_set_error (&v->display,
80 ("Error: the number of periods must be positive"));
81 mp_set_from_integer(0, t);
86 void
87 calc_fv(MPNumber *t, MPNumber *pmt, MPNumber *pint, MPNumber *n)
90 /* Fv - pmt (periodic payment).
91 * pint (periodic interest rate).
92 * n (number of periods).
94 * RESULT = pmt * (pow(1 + pint, n) - 1) / pint
97 MPNumber MP1, MP2, MP3, MP4;
99 mp_add_integer(pint, 1, &MP1);
100 mp_xpowy(&MP1, n, &MP2);
101 mp_add_integer(&MP2, -1, &MP3);
102 mp_multiply(pmt, &MP3, &MP4);
103 mp_divide(&MP4, pint, t);
107 void
108 calc_gpm(MPNumber *t, MPNumber *cost, MPNumber *margin)
111 /* Gpm - cost (cost of sale).
112 * margin (gross profit margin.
114 * RESULT = cost / (1 - margin)
117 MPNumber MP1, MP2;
119 mp_set_from_integer(1, &MP1);
120 mp_subtract(&MP1, margin, &MP2);
121 mp_divide(cost, &MP2, t);
125 void
126 calc_pmt(MPNumber *t, MPNumber *prin, MPNumber *pint, MPNumber *n)
129 /* Pmt - prin (principal).
130 * pint (periodic interest rate).
131 * n (term).
133 * RESULT = prin * (pint / (1 - pow(pint + 1, -1 * n)))
136 MPNumber MP1, MP2, MP3, MP4;
138 mp_add_integer(pint, 1, &MP1);
139 mp_multiply_integer(n, -1, &MP2);
140 mp_xpowy(&MP1, &MP2, &MP3);
141 mp_multiply_integer(&MP3, -1, &MP4);
142 mp_add_integer(&MP4, 1, &MP1);
143 mp_divide(pint, &MP1, &MP2);
144 mp_multiply(prin, &MP2, t);
148 void
149 calc_pv(MPNumber *t, MPNumber *pmt, MPNumber *pint, MPNumber *n)
152 /* Pv - pmt (periodic payment).
153 * pint (periodic interest rate).
154 * n (term).
156 * RESULT = pmt * (1 - pow(1 + pint, -1 * n)) / pint
159 MPNumber MP1, MP2, MP3, MP4;
161 mp_add_integer(pint, 1, &MP1);
162 mp_multiply_integer(n, -1, &MP2);
163 mp_xpowy(&MP1, &MP2, &MP3);
164 mp_multiply_integer(&MP3, -1, &MP4);
165 mp_add_integer(&MP4, 1, &MP1);
166 mp_divide(&MP1, pint, &MP2);
167 mp_multiply(pmt, &MP2, t);
171 void
172 calc_rate(MPNumber *t, MPNumber *fv, MPNumber *pv, MPNumber *n)
175 /* Rate - fv (future value).
176 * pv (present value).
177 * n (term).
179 * RESULT = pow(fv / pv, 1 / n) - 1
182 MPNumber MP1, MP2, MP3, MP4;
184 mp_divide(fv, pv, &MP1);
185 mp_set_from_integer(1, &MP2);
186 mp_divide(&MP2, n, &MP3);
187 mp_xpowy(&MP1, &MP3, &MP4);
188 mp_add_integer(&MP4, -1, t);
192 void
193 calc_sln(MPNumber *t, MPNumber *cost, MPNumber *salvage, MPNumber *life)
196 /* Sln - cost (cost of the asset).
197 * salvage (salvage value of the asset).
198 * life (useful life of the asset).
200 * RESULT = (cost - salvage) / life
203 MPNumber MP1;
204 mp_subtract(cost, salvage, &MP1);
205 mp_divide(&MP1, life, t);
209 void
210 calc_syd(MPNumber *t, MPNumber *cost, MPNumber *salvage, MPNumber *life, MPNumber *period)
213 /* Syd - cost (cost of the asset).
214 * salvage (salvage value of the asset).
215 * life (useful life of the asset).
216 * period (period for which depreciation is computed).
218 * RESULT = (cost - salvage) * (life - period + 1) /
219 * (life * (life + 1)) / 2
222 MPNumber MP1, MP2, MP3, MP4;
224 mp_subtract(life, period, &MP2);
225 mp_add_integer(&MP2, 1, &MP3);
226 mp_add_integer(life, 1, &MP2);
227 mp_multiply(life, &MP2, &MP4);
228 mp_set_from_integer(2, &MP2);
229 mp_divide(&MP4, &MP2, &MP1);
230 mp_divide(&MP3, &MP1, &MP2);
231 mp_subtract(cost, salvage, &MP1);
232 mp_multiply(&MP1, &MP2, t);
236 void
237 calc_term(MPNumber *t, MPNumber *pmt, MPNumber *fv, MPNumber *pint)
240 /* Term - pmt (periodic payment).
241 * fv (future value).
242 * pint (periodic interest rate).
244 * RESULT = log(1 + (fv * pint / pmt)) / log(1 + pint)
247 MPNumber MP1, MP2, MP3, MP4;
249 mp_add_integer(pint, 1, &MP1);
250 mp_ln(&MP1, &MP2);
251 mp_multiply(fv, pint, &MP1);
252 mp_divide(&MP1, pmt, &MP3);
253 mp_add_integer(&MP3, 1, &MP4);
254 mp_ln(&MP4, &MP1);
255 mp_divide(&MP1, &MP2, t);
258 void
259 do_finc_expression(int function, MPNumber *arg1, MPNumber *arg2, MPNumber *arg3, MPNumber *arg4)
261 MPNumber result;
262 switch (function) {
263 case FINC_CTRM_DIALOG:
264 calc_ctrm(&result, arg1, arg2, arg3);
265 break;
266 case FINC_DDB_DIALOG:
267 calc_ddb(&result, arg1, arg2, arg3);
268 break;
269 case FINC_FV_DIALOG:
270 calc_fv(&result, arg1, arg2, arg3);
271 break;
272 case FINC_GPM_DIALOG:
273 calc_gpm(&result, arg1, arg2);
274 break;
275 case FINC_PMT_DIALOG:
276 calc_pmt(&result, arg1, arg2, arg3);
277 break;
278 case FINC_PV_DIALOG:
279 calc_pv(&result, arg1, arg2, arg3);
280 break;
281 case FINC_RATE_DIALOG:
282 calc_rate(&result, arg1, arg2, arg3);
283 break;
284 case FINC_SLN_DIALOG:
285 calc_sln(&result, arg1, arg2, arg3);
286 break;
287 case FINC_SYD_DIALOG:
288 calc_syd(&result, arg1, arg2, arg3, arg4);
289 break;
290 case FINC_TERM_DIALOG:
291 calc_term(&result, arg1, arg2, arg3);
292 break;
294 display_set_number(&v->display, &result);