1 /* $XConsortium: functions.c /main/6 1996/09/25 09:36:28 mustafa $ */
4 * Contains the many of the functions (i.e. do_*) which actually do *
5 * (at least start) the calculations. *
7 * (c) Copyright 1993, 1994 Hewlett-Packard Company *
8 * (c) Copyright 1993, 1994 International Business Machines Corp. *
9 * (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
10 * (c) Copyright 1993, 1994 Novell, Inc. *
20 extern char *base_str[] ; /* Strings for each base value. */
21 extern char *dtype_str[] ; /* Strings for each display mode value. */
22 extern char *mode_str[] ; /* Strings for each mode value. */
23 extern char *ttype_str[] ; /* Strings for each trig type value. */
24 extern char *vstrs[] ; /* Various strings. */
26 extern struct button buttons[] ; /* Calculator button values. */
27 extern struct button mode_buttons[] ; /* Special "mode" buttons. */
28 extern struct menu_entry menu_entries[] ; /* All the menu strings. */
30 extern Vars v ; /* Calctool variables and options. */
32 double mods[] = { 1.0, 1.0e-1, 1.0e-2, 1.0e-3, 1.0e-4,
33 1.0e-5, 1.0e-6, 1.0e-7, 1.0e-8, 1.0e-9,
34 1.0e-10, 1.0e-11, 1.0e-12, 1.0e-13, 1.0e-14,
35 1.0e-15, 1.0e-16, 1.0e-17, 1.0e-18, 1.0e-19 };
39 do_accuracy() /* Set display accuracy. */
43 for (i = ACC_START; i <= ACC_END; i++)
44 if (v->current == menu_entries[i].val)
46 v->accuracy = char_val(v->current) ;
55 do_ascii() /* Convert ASCII value. */
64 do_base() /* Change the current base setting. */
66 if (v->current == BASE_BIN) v->base = BIN ;
67 else if (v->current == BASE_OCT) v->base = OCT ;
68 else if (v->current == BASE_DEC) v->base = DEC ;
69 else if (v->current == BASE_HEX) v->base = HEX ;
79 grey_buttons(v->base) ;
80 show_display(v->MPdisp_val) ;
81 set_option_menu((int) BASEITEM, (int)v->base);
83 if (v->rstate) make_registers(MEM) ;
84 if (v->frstate) make_registers(FIN) ;
88 do_business() /* Perform special business mode calculations. */
90 Boolean need_show = TRUE;
91 char *display_number = NULL;
92 int MPbv[MP_SIZE], MP1[MP_SIZE], MP2[MP_SIZE], MP3[MP_SIZE], MP4[MP_SIZE] ;
94 int i, len, val, val2, accSav ;
97 if (IS_KEY(v->current, KEY_CTRM))
99 /* Cterm - FMEM1 = int (periodic interest rate).
100 * FMEM2 = Pv (present value).
101 * FMEM4 = Fv (future value).
103 * RESULT = log(FMEM4 / FMEM2) / log(1 + FMEM1)
105 if(v->MPfvals[1] == 0.0 || v->MPfvals[2] == 0.0 || v->MPfvals[4] == 0.0)
107 char *errorMsg, *tmp;
109 /* want to undraw the button first */
110 draw_button(19, 0, 4, 3, FALSE);
111 errorMsg = GETMESSAGE(5, 7, "Can't calculate 'Compound Term'\nwithout a non zero interest rate,\na non zero Present value, and\na non zero Future value.\n");
112 tmp = XtNewString(errorMsg);
119 result = log(v->MPfvals[4] / v->MPfvals[2]) / log(1.0 + (v->MPfvals[1] / 1200));
122 mpcdm(&result, v->MPdisp_val) ;
123 make_registers(FIN) ;
128 else if (IS_KEY(v->current, KEY_DDB))
131 /* Ddb - MEM0 = cost (amount paid for asset).
132 * MEM1 = salvage (value of asset at end of its life).
133 * MEM2 = life (useful life of the asset).
134 * MEM3 = period (time period for depreciation allowance).
137 * for (i = 0; i < MEM3; i++)
139 * VAL = ((MEM0 - bv) * 2) / MEM2
147 mpcmi(v->MPmvals[3], &len) ;
148 for (i = 0; i < len; i++)
150 mpsub(v->MPmvals[0], MPbv, MP1) ;
152 mpmuli(MP1, &val, MP2) ;
153 mpdiv(MP2, v->MPmvals[2], v->MPdisp_val) ;
155 mpadd(MP1, v->MPdisp_val, MPbv) ;
158 else if (IS_KEY(v->current, KEY_FV))
161 /* Fv - FMEM3 = pmt (periodic payment).
162 * FMEM1 = int (periodic interest rate).
163 * FMEM2 = Pv (present value).
164 * FMEM0 = n (number of periods).
167 if(v->MPfvals[0] == 0.0 || v->MPfvals[1] == 0.0 ||
168 (v->MPfvals[2] == 0.0 && v->MPfvals[3] == 0.0) || v->funstate == 0)
173 doerr(GETMESSAGE(5, 2, "ERROR: No Solution"));
177 /* set FV register */
178 mpcmd(v->MPdisp_val, &(v->MPfvals[4]));
182 if ((w = 1.0 + v->MPfvals[1] / (v->MPfvals[5] * 100.0)) == 1.0)
183 result = -(v->MPfvals[2] + v->MPfvals[0] * v->MPfvals[3]);
185 result = -(v->MPfvals[2] * pow(w, v->MPfvals[0]) +
186 v->MPfvals[3] * (pow(w, v->MPfvals[0]) - 1.0) *
187 pow(w, 0.0) / (w - 1.0));
188 mpcdm(&result, v->MPdisp_val) ;
190 if(strcmp(v->display, GETMESSAGE(3, 364, "Error")) != 0)
191 mpcmd(v->MPdisp_val, &(v->MPfvals[4]));
192 make_registers(FIN) ;
195 else if (IS_KEY(v->current, KEY_PMT))
198 /* Pmt - FMEM0 = prin (principal).
199 * FMEM1 = int (periodic interest rate).
202 * RESULT = FMEM0 * (FMEM1 / (1 - pow(FMEM1 + 1, -1 * FMEM2)))
205 if(v->MPfvals[0] == 0.0 || v->MPfvals[1] == 0.0 ||
206 (v->MPfvals[2] == 0.0 && v->MPfvals[4] == 0.0) || v->funstate == 0)
211 doerr(GETMESSAGE(5, 2, "ERROR: No Solution"));
215 /* set Payment register */
216 mpcmd(v->MPdisp_val, &(v->MPfvals[3]));
221 if ((w = 1.0 + v->MPfvals[1] / (v->MPfvals[5] * 100.0)) == 1.0)
222 result = -(v->MPfvals[4] + v->MPfvals[2]) / v->MPfvals[0];
224 result = -(v->MPfvals[2] * pow(w, v->MPfvals[0]) +
225 v->MPfvals[4]) * (w - 1.0) /
226 ((pow(w, v->MPfvals[0]) - 1.0) * pow(w, 0.0));
227 mpcdm(&result, v->MPdisp_val) ;
229 if(strcmp(v->display, GETMESSAGE(3, 364, "Error")) != 0)
230 mpcmd(v->MPdisp_val, &(v->MPfvals[3]));
231 make_registers(FIN) ;
234 else if (IS_KEY(v->current, KEY_PV))
237 /* Pv - FMEM0 = pmt (periodic payment).
238 * FMEM1 = int (periodic interest rate).
241 * RESULT = FMEM0 * (1 - pow(1 + FMEM1, -1 * FMEM2)) / FMEM1
244 if(v->MPfvals[0] == 0.0 || v->MPfvals[1] == 0.0 || v->MPfvals[3] == 0.0 || v->funstate == 0)
249 doerr(GETMESSAGE(5, 2, "ERROR: No Solution"));
253 /* set PV register */
254 mpcmd(v->MPdisp_val, &(v->MPfvals[2]));
258 if ((w = 1.0 + v->MPfvals[1] / (v->MPfvals[5] * 100.0)) == 1.0)
259 result = -(v->MPfvals[4] + v->MPfvals[0] * v->MPfvals[3]);
261 result = -(v->MPfvals[4] / pow(w, v->MPfvals[0]) +
262 v->MPfvals[3] * (pow(w, v->MPfvals[0]) - 1.0) *
263 pow(w, 0.0 - v->MPfvals[0]) / (w - 1.0));
264 mpcdm(&result, v->MPdisp_val) ;
266 if(strcmp(v->display, GETMESSAGE(3, 364, "Error")) != 0)
267 mpcmd(v->MPdisp_val, &(v->MPfvals[2]));
268 make_registers(FIN) ;
271 else if (IS_KEY(v->current, KEY_RATE))
273 /* Rate - MEM0 = fv (future value).
274 * MEM1 = pv (present value).
277 * RESULT = pow(MEM0 / MEM1, 1 / MEM2) - 1
279 if(v->MPfvals[0] == 0.0 || (v->MPfvals[2] == 0.0 && v->MPfvals[3] == 0.0)
280 || (v->MPfvals[3] == 0.0 && v->MPfvals[4] == 0.0)
286 doerr(GETMESSAGE(5, 2, "ERROR: No Solution"));
291 accSav = v->accuracy;
293 display_number = make_number(v->MPdisp_val, FALSE);
294 MPstr_to_num(display_number, DEC, v->MPdisp_val);
295 /* set RATE register */
296 mpcmd(v->MPdisp_val, &(v->MPfvals[1]));
297 v->accuracy = accSav;
302 compute_i(&(v->MPfvals[1]));
303 mpcdm(&(v->MPfvals[1]), v->MPdisp_val);
304 accSav = v->accuracy;
306 display_number = make_number(v->MPdisp_val, FALSE);
307 MPstr_to_num(display_number, DEC, v->MPdisp_val);
308 v->accuracy = accSav;
312 make_registers(FIN) ;
315 STRCPY(v->display, display_number);
316 set_item(DISPLAYITEM, v->display);
319 else if (IS_KEY(v->current, KEY_SLN))
322 /* Sln - MEM0 = cost (cost of the asset).
323 * MEM1 = salvage (salvage value of the asset).
324 * MEM2 = life (useful life of the asset).
326 * RESULT = (MEM0 - MEM1) / MEM2
329 mpsub(v->MPmvals[0], v->MPmvals[1], MP1) ;
330 mpdiv(MP1, v->MPmvals[2], v->MPdisp_val) ;
332 else if (IS_KEY(v->current, KEY_SYD))
335 /* Syd - MEM0 = cost (cost of the asset).
336 * MEM1 = salvage (salvage value of the asset).
337 * MEM2 = life (useful life of the asset).
338 * MEM3 = period (period for which depreciation is computed).
340 * RESULT = ((MEM0 - MEM1) * (MEM2 - MEM3 + 1)) /
341 * (MEM2 * (MEM2 + 1) / 2)
344 mpsub(v->MPmvals[2], v->MPmvals[3], MP2) ;
346 mpaddi(MP2, &val, MP3) ;
347 mpaddi(v->MPmvals[2], &val, MP2) ;
348 mpmul(v->MPmvals[2], MP2, MP4) ;
351 mpdiv(MP4, MP2, MP1) ;
352 mpdiv(MP3, MP1, MP2) ;
353 mpsub(v->MPmvals[0], v->MPmvals[1], MP1) ;
354 mpmul(MP1, MP2, v->MPdisp_val) ;
356 else if (IS_KEY(v->current, KEY_TERM))
359 /* Term - FMEM0 = pmt (periodic payment).
360 * FMEM1 = fv (future value).
361 * FMEM2 = int (periodic interest rate).
363 * RESULT = log(1 + (FMEM1 * FMEM2 / FMEM0)) / log(1 + FMEM2)
366 if(v->MPfvals[1] == 0.0 || (v->MPfvals[2] == 0.0 && v->MPfvals[4] == 0)
367 || v->MPfvals[3] == 0.0 || v->funstate == 0)
372 doerr(GETMESSAGE(5, 2, "ERROR: No Solution"));
376 /* set Term register */
377 mpcmd(v->MPdisp_val, &(v->MPfvals[0]));
381 if ((w = 1.0 + v->MPfvals[1] / (v->MPfvals[5] * 100.0)) == 1.0)
382 result = -(v->MPfvals[4] + v->MPfvals[2]) / v->MPfvals[3];
385 double wdb = pow(w, 0.0);
387 result = log((v->MPfvals[3] * wdb / (w - 1.0) - v->MPfvals[4]) /
388 (v->MPfvals[2] * pow(w, 0.0) + v->MPfvals[3] * wdb /
389 (w - 1.0))) / log(w);
392 if(strcmp(v->display, GETMESSAGE(3, 364, "Error")) != 0)
393 mpcdm(&result, v->MPdisp_val) ;
395 if(strcmp(v->display, GETMESSAGE(3, 364, "Error")) != 0)
396 mpcmd(v->MPdisp_val, &(v->MPfvals[0]));
397 make_registers(FIN) ;
400 else if (IS_KEY(v->current, KEY_PYR))
402 mpcmd(v->MPdisp_val, &(v->MPfvals[5]));
403 result = do_round(v->MPfvals[5], 0);
407 v->MPfvals[5] = result;
408 make_registers(FIN) ;
411 else if (IS_KEY(v->current, KEY_FCLR))
417 /* clear Term register */
418 mpcmd(MP1, &(v->MPfvals[0])) ;
420 /* clear %/YR register */
421 mpcmd(MP1, &(v->MPfvals[1])) ;
423 /* clear PV register */
424 mpcmd(MP1, &(v->MPfvals[2])) ;
426 /* clear Payment register */
427 mpcmd(MP1, &(v->MPfvals[3])) ;
429 /* clear FV register */
430 mpcmd(MP1, &(v->MPfvals[4])) ;
434 mpcmd(MP1, &(v->MPfvals[5])) ;
439 if (need_show == TRUE)
440 show_display(v->MPdisp_val) ;
447 do_calc() /* Perform arithmetic calculation and display result. */
452 /* the financial state is false - last key was not a fin. key */
455 if (!(v->opsptr && !v->show_paren)) /* Don't do if processing parens. */
456 if (IS_KEY(v->current, KEY_EQ) && IS_KEY(v->old_cal_value, KEY_EQ))
458 mpstr(v->MPdisp_val, v->MPresult) ;
460 mpstr(v->MPlast_input, v->MPdisp_val) ;
462 if (!IS_KEY(v->current, KEY_EQ) && IS_KEY(v->old_cal_value, KEY_EQ))
465 if (IS_KEY(v->cur_op, KEY_COS) || /* Cos */
466 IS_KEY(v->cur_op, KEY_SIN) || /* Sin */
467 IS_KEY(v->cur_op, KEY_TAN) || /* Tan */
468 v->cur_op == '?') /* Undefined */
469 mpstr(v->MPdisp_val, v->MPresult) ;
471 else if (IS_KEY(v->cur_op, KEY_ADD)) /* Addition */
472 mpadd(v->MPresult, v->MPdisp_val, v->MPresult) ;
474 else if (IS_KEY(v->cur_op, KEY_SUB)) /* Subtraction. */
475 mpsub(v->MPresult, v->MPdisp_val, v->MPresult) ;
477 else if (v->cur_op == '*' ||
478 IS_KEY(v->cur_op, KEY_MUL)) /* Multiplication */
479 mpmul(v->MPresult, v->MPdisp_val, v->MPresult) ;
481 else if (IS_KEY(v->cur_op, KEY_DIV)) /* Division. */
482 mpdiv(v->MPresult, v->MPdisp_val, v->MPresult) ;
484 else if (IS_KEY(v->cur_op, KEY_PER)) /* % */
486 mpmul(v->MPresult, v->MPdisp_val, v->MPresult) ;
487 MPstr_to_num("0.01", DEC, MP1) ;
488 mpmul(v->MPresult, MP1, v->MPresult) ;
491 else if (IS_KEY(v->cur_op, KEY_YTOX)) /* y^x */
492 mppwr2(v->MPresult, v->MPdisp_val, v->MPresult) ;
494 else if (IS_KEY(v->cur_op, KEY_AND)) /* And */
496 mpcmd(v->MPresult, &dres) ;
497 mpcmd(v->MPdisp_val, &dval) ;
498 dres = setbool((BOOLEAN)(ibool(dres) & ibool(dval))) ;
499 mpcdm(&dres, v->MPresult) ;
502 else if (IS_KEY(v->cur_op, KEY_OR)) /* Or */
504 mpcmd(v->MPresult, &dres) ;
505 mpcmd(v->MPdisp_val, &dval) ;
506 dres = setbool((BOOLEAN)(ibool(dres) | ibool(dval))) ;
507 mpcdm(&dres, v->MPresult) ;
510 else if (IS_KEY(v->cur_op, KEY_XOR)) /* Xor */
512 mpcmd(v->MPresult, &dres) ;
513 mpcmd(v->MPdisp_val, &dval) ;
514 dres = setbool((BOOLEAN)(ibool(dres) ^ ibool(dval))) ;
515 mpcdm(&dres, v->MPresult) ;
518 else if (IS_KEY(v->cur_op, KEY_XNOR)) /* Xnor */
520 mpcmd(v->MPresult, &dres) ;
521 mpcmd(v->MPdisp_val, &dval) ;
522 dres = setbool((BOOLEAN)(~ibool(dres) ^ ibool(dval))) ;
523 mpcdm(&dres, v->MPresult) ;
526 else if (IS_KEY(v->cur_op, KEY_EQ)) /* do nothing. */ ; /* Equals */
528 show_display(v->MPresult) ;
530 if (!(IS_KEY(v->current, KEY_EQ) && IS_KEY(v->old_cal_value, KEY_EQ)))
531 mpstr(v->MPdisp_val, v->MPlast_input) ;
533 mpstr(v->MPresult, v->MPdisp_val) ;
535 v->cur_op = v->current ;
537 v->old_cal_value = v->current ;
538 v->new_input = v->key_exp = 0 ;
543 do_clear() /* Clear the calculator display and re-initialise. */
546 if (v->error) set_item(DISPLAYITEM, "") ;
554 if (v->current >= '0' && v->current <= '9')
556 mpstr(v->MPcon_vals[char_val(v->current)], v->MPdisp_val) ;
557 show_display(v->MPdisp_val) ;
563 do_delete() /* Remove the last numeric character typed. */
565 if (strlen(v->display))
566 v->display[strlen(v->display)-1] = '\0' ;
568 /* If we were entering a scientific number, and we have backspaced over
569 * the exponent sign, then this reverts to entering a fixed point number.
572 if (v->key_exp && !(strchr(v->display, '+')))
575 v->display[strlen(v->display)-1] = '\0' ;
576 set_item(OPITEM, "") ;
579 /* If we've backspaced over the numeric point, clear the pointed flag. */
581 if (v->pointed && !(strchr(v->display, '.'))) v->pointed = 0 ;
583 if(strcmp(v->display, "") == 0)
586 set_item(DISPLAYITEM, v->display) ;
587 MPstr_to_num(v->display, v->base, v->MPdisp_val) ;
592 do_exchange() /* Exchange display with memory register. */
594 int i, MPtemp[MP_SIZE] ;
596 for (i = MEM_START; i <= MEM_END; i++)
597 if (v->current == menu_entries[i].val)
599 mpstr(v->MPdisp_val, MPtemp) ;
600 mpstr(v->MPmvals[char_val(v->current)], v->MPdisp_val) ;
601 mpstr(MPtemp, v->MPmvals[char_val(v->current)]) ;
602 make_registers(MEM) ;
609 do_expno() /* Get exponential number. */
611 /* the financial state is false - last key was not a fin. key */
614 v->pointed = (strchr(v->display, '.') != NULL) ;
617 STRCPY(v->display, "1.0 +") ;
618 v->new_input = v->pointed = 1 ;
620 else if (!v->pointed)
622 STRNCAT(v->display, ". +", 3) ;
625 else if (!v->key_exp) STRNCAT(v->display, " +", 2) ;
628 v->exp_posn = strchr(v->display, '+') ;
629 set_item(DISPLAYITEM, v->display) ;
630 MPstr_to_num(v->display, v->base, v->MPdisp_val) ;
635 do_factorial(MPval, MPres) /* Calculate the factorial of MPval. */
639 int i, MPa[MP_SIZE], MP1[MP_SIZE], MP2[MP_SIZE] ;
641 /* NOTE: do_factorial, on each iteration of the loop, will attempt to
642 * convert the current result to a double. If v->error is set,
643 * then we've overflowed. This is to provide the same look&feel
646 * XXX: Needs to be improved. Shouldn't need to convert to a double in
647 * order to check this.
654 if (mpeq(MPval, MP1) && mpge(MPval, MP2)) /* Only positive integers. */
657 if (mpeq(MP1, MP2)) /* Special case for 0! */
664 if (!i) matherr((struct exception *) NULL) ;
668 mpmuli(MPa, &i, MPa) ;
670 if (v->error) break ;
674 else matherr((struct exception *) NULL) ;
680 do_frame() /* Exit dtcalc. */
686 do_function() /* Perform a user defined function. */
688 enum fcp_type scurwin ;
689 int fno, scolumn, srow ;
692 scolumn = v->column ;
693 scurwin = v->curwin ;
695 if (v->current >= '0' && v->current <= '9')
697 fno = char_val(v->current) ;
698 if(strcmp(v->fun_vals[fno], "") != 0)
699 process_str(v->fun_vals[fno], M_FUN) ;
701 v->curwin = scurwin ;
703 v->column = scolumn ;
711 int i, MP1[MP_SIZE], MP2[MP_SIZE] ;
713 /* the financial state is false - last key was not a fin. key */
716 if (IS_KEY(v->current, KEY_HYP)) /* Hyp */
718 v->hyperbolic = !v->hyperbolic ;
719 set_item(HYPITEM, (v->hyperbolic) ? vstrs[(int) V_HYP]
723 else if (IS_KEY(v->current, KEY_INV)) /* Inv */
725 v->inverse = !v->inverse ;
726 set_item(INVITEM, (v->inverse) ? vstrs[(int) V_INV]
730 else if (IS_KEY(v->current, KEY_32)) /* &32 */
732 mpcmd(v->MPdisp_val, &dval) ;
733 dval2 = ibool2(dval);
735 doerr(GETMESSAGE(5, 6, "ERR:Num too large for operation"));
738 dval = setbool((BOOLEAN)dval2) ;
739 mpcdm(&dval, v->MPdisp_val) ;
743 else if (IS_KEY(v->current, KEY_16)) /* &16 */
745 mpcmd(v->MPdisp_val, &dval) ;
746 dval2 = ibool2(dval);
748 doerr(GETMESSAGE(5, 6, "ERR:Num too large for operation"));
751 dval = setbool((BOOLEAN)(ibool(dval2) & 0xffff)) ;
752 mpcdm(&dval, v->MPdisp_val) ;
756 else if (IS_KEY(v->current, KEY_ETOX)) /* e^x */
758 mpstr(v->MPdisp_val, MP1) ;
759 mpexp(MP1, v->MPdisp_val) ;
762 else if (IS_KEY(v->current, KEY_TTOX)) /* 10^x */
766 mppwr2(MP1, v->MPdisp_val, v->MPdisp_val) ;
769 else if (IS_KEY(v->current, KEY_LN)) /* Ln */
771 mpstr(v->MPdisp_val, MP1) ;
772 mpln(MP1, v->MPdisp_val) ;
775 else if (IS_KEY(v->current, KEY_LOG)) /* Log */
777 mplog10(v->MPdisp_val, v->MPdisp_val) ;
780 else if (IS_KEY(v->current, KEY_RAND)) /* Rand */
783 mpcdm(&dval, v->MPdisp_val) ;
786 else if (IS_KEY(v->current, KEY_SQRT)) /* Sqrt */
788 mpstr(v->MPdisp_val, MP1) ;
789 mpsqrt(MP1, v->MPdisp_val) ;
792 else if (IS_KEY(v->current, KEY_NOT)) /* Not */
794 mpcmd(v->MPdisp_val, &dval) ;
795 dval = setbool((BOOLEAN)~ibool(dval)) ;
796 mpcdm(&dval, v->MPdisp_val) ;
799 else if (IS_KEY(v->current, KEY_REC)) /* 1/x */
803 mpstr(v->MPdisp_val, MP2) ;
804 mpdiv(MP1, MP2, v->MPdisp_val) ;
806 else if (IS_KEY(v->current, KEY_FACT)) /* x! */
808 do_factorial(v->MPdisp_val, MP1) ;
809 mpstr(MP1, v->MPdisp_val) ;
811 else if (IS_KEY(v->current, KEY_SQR)) /* x^2 */
813 mpstr(v->MPdisp_val, MP1) ;
814 mpmul(MP1, MP1, v->MPdisp_val) ;
817 else if (IS_KEY(v->current, KEY_CHS)) /* +/- */
821 if (*v->exp_posn == '+') *v->exp_posn = '-' ;
822 else *v->exp_posn = '+' ;
823 set_item(DISPLAYITEM, v->display) ;
824 MPstr_to_num(v->display, v->base, v->MPdisp_val) ;
829 mpneg(v->MPdisp_val, v->MPdisp_val) ;
830 mpstr(v->MPdisp_val, v->MPlast_input) ;
833 show_display(v->MPdisp_val) ;
838 do_keys() /* Display/undisplay the dtcalc key values. */
840 v->tstate = !v->tstate ;
845 do_mode() /* Set special calculator mode. */
847 if (v->current == MODE_FIN) v->modetype = FINANCIAL ;
848 else if (v->current == MODE_LOG) v->modetype = LOGICAL ;
849 else if (v->current == MODE_SCI) v->modetype = SCIENTIFIC ;
852 v->curwin = FCP_KEY ;
857 do_none() /* Null routine for empty buttons. */
867 static int maxvals[4] = { 1, 7, 9, 15 } ;
869 /* the financial state is false - last key was not a fin. key */
872 nextchar = v->current ;
873 n = v->current - '0' ;
874 if (v->base == HEX && v->current >= 'a' && v->current <= 'f')
876 nextchar -= 32 ; /* Convert to uppercase hex digit. */
877 n = v->current - 'a' + 10 ;
879 if (n > maxvals[(int) v->base])
887 SPRINTF(v->display, "%c", nextchar) ;
892 len = strlen(v->display) ;
893 if (len < MAX_DIGITS)
895 v->display[len] = nextchar ;
896 v->display[len+1] = '\0' ;
901 set_item(DISPLAYITEM, v->display) ;
902 MPstr_to_num(v->display, v->base, v->MPdisp_val) ;
908 do_numtype() /* Set number type (engineering, fixed or scientific). */
910 if (v->current == DISP_ENG) v->dtype = ENG ;
911 else if (v->current == DISP_FIX) v->dtype = FIX ;
912 else if (v->current == DISP_SCI) v->dtype = SCI ;
915 set_numtype(v->dtype);
919 enum num_type dtype ;
922 show_display(v->MPdisp_val) ;
923 set_option_menu((int) NUMITEM, (int)v->dtype);
924 if (v->rstate) make_registers(MEM) ;
925 if (v->frstate) make_registers(FIN) ;
934 /* the financial state is false - last key was not a fin. key */
937 /* Check to see if this is the first outstanding parenthesis. If so, and
938 * their is a current operation already defined, then add the current
939 * operation to the parenthesis expression being displayed.
940 * Increment parentheses count, and add the open paren to the expression.
943 if (IS_KEY(v->current, KEY_LPAR))
945 if (v->noparens == 0)
947 /* if not in default state, put the operand between the display
948 value and the paren, else just put the paren */
951 /* there is no paren, and there is no current operand ... Let's
952 make the current operand into a "x" */
959 /* if the current op is an '=' and the result in the display is
960 zero, we want to ignore the display */
963 mpcmd(v->MPdisp_val, &tmpdb);
967 STRCPY(v->display, "") ;
968 set_item(DISPLAYITEM, v->display) ;
975 paren_disp(v->cur_op) ;
981 paren_disp(v->cur_op) ;
986 STRCPY(v->display, "") ;
987 set_item(DISPLAYITEM, v->display) ;
992 int len = strlen(v->display);
994 if(v->display[len - 1] >= '0' && v->display[len - 1] <= '9')
995 paren_disp(v->cur_op) ;
998 v->pending = v->current ;
1002 /* If we haven't had any left brackets yet, and this is a right bracket,
1003 * then just ignore it.
1004 * Decrement the bracket count. If the count is zero, then process the
1005 * parenthesis expression.
1008 else if (IS_KEY(v->current, KEY_RPAR))
1010 if (!v->noparens) return ;
1015 paren_disp(v->current) ;
1017 while (*ptr != '(') ptr++ ;
1018 while (*ptr != '\0') process_parens(*ptr++) ;
1022 paren_disp(v->current) ;
1029 /* the financial state is false - last key was not a fin. key */
1032 /* Certain pending operations which are half completed, force the numeric
1033 * keypad to be reshown (assuming they already aren't).
1035 * Con, Exch, Fun, Sto, Rcl and Acc show buttons 0 - 9.
1036 * < and > show buttons 0 - f.
1041 if (IS_KEY(v->current, KEY_CON) || /* Con. */
1042 IS_KEY(v->current, KEY_EXCH) || /* Exch. */
1043 IS_KEY(v->current, KEY_FUN) || /* Fun. */
1044 IS_KEY(v->current, KEY_STO) || /* Sto. */
1045 IS_KEY(v->current, KEY_RCL) || /* Rcl. */
1046 IS_KEY(v->current, KEY_ACC)) /* Acc. */
1048 if (IS_KEY(v->current, KEY_LSFT) ||
1049 IS_KEY(v->current, KEY_RSFT))
1053 if (IS_KEY(v->pending, KEY_BASE)) do_base() ; /* Base */
1054 else if (IS_KEY(v->pending, KEY_DISP)) do_numtype() ; /* Disp */
1055 else if (IS_KEY(v->pending, KEY_TRIG)) do_trigtype() ; /* Trig */
1056 else if (IS_KEY(v->pending, KEY_CON)) do_constant() ; /* Con */
1057 else if (IS_KEY(v->pending, KEY_EXCH)) do_exchange() ; /* Exch */
1058 else if (IS_KEY(v->pending, KEY_FUN)) do_function() ; /* Fun */
1059 else if (IS_KEY(v->pending, KEY_STO) || /* Sto */
1060 IS_KEY(v->pending, KEY_RCL)) /* Rcl */
1063 if (IS_KEY(v->pending_op, KEY_ADD) ||
1064 IS_KEY(v->pending_op, KEY_SUB) ||
1065 IS_KEY(v->pending_op, KEY_MUL) ||
1066 IS_KEY(v->pending_op, KEY_DIV)) return ;
1068 else if (IS_KEY(v->pending, KEY_LSFT) || /* < */
1069 IS_KEY(v->pending, KEY_RSFT)) do_shift() ; /* > */
1070 else if (IS_KEY(v->pending, KEY_ACC)) do_accuracy() ; /* Acc */
1071 else if (IS_KEY(v->pending, KEY_MODE)) do_mode() ; /* Mode */
1072 else if (IS_KEY(v->pending, KEY_LPAR)) /* ( */
1077 else if (!v->pending)
1079 save_pending_values(v->current) ;
1080 v->pending_op = KEY_EQ ;
1084 show_display(v->MPdisp_val) ;
1085 if (v->error) set_item(OPITEM, vstrs[(int) V_CLR]) ;
1086 else set_item(OPITEM, "") ; /* Redisplay pending op. (if any). */
1090 grey_buttons(v->base) ; /* Just show numeric keys for current base. */
1095 do_point() /* Handle numeric point. */
1097 /* the financial state is false - last key was not a fin. key */
1104 STRCPY(v->display, ".") ;
1107 else STRNCAT(v->display, ".", 1) ;
1112 set_item(DISPLAYITEM, v->display) ;
1113 MPstr_to_num(v->display, v->base, v->MPdisp_val) ;
1122 /* the financial state is false - last key was not a fin. key */
1125 if (IS_KEY(v->current, KEY_ABS)) /* Abs */
1127 mpstr(v->MPdisp_val, MP1) ;
1128 mpabs(MP1, v->MPdisp_val) ;
1130 else if (IS_KEY(v->current, KEY_FRAC)) /* Frac */
1132 mpstr(v->MPdisp_val, MP1) ;
1133 mpcmf(MP1, v->MPdisp_val) ;
1135 else if (IS_KEY(v->current, KEY_INT)) /* Int */
1137 mpstr(v->MPdisp_val, MP1) ;
1138 mpcmim(MP1, v->MPdisp_val) ;
1140 show_display(v->MPdisp_val) ;
1145 do_shift() /* Perform bitwise shift on display value. */
1147 int i, MPtemp[MP_SIZE], shift ;
1151 shift = char_val(v->current) ;
1152 if(strcmp(v->snum, v->display) != 0)
1154 MPstr_to_num(v->display, v->base, MPtemp) ;
1155 mpcmd(MPtemp, &dval) ;
1158 mpcmd(v->MPdisp_val, &dval) ;
1159 temp = ibool(dval) ;
1161 if (IS_KEY(v->pending, KEY_LSFT)) temp = temp << shift ;
1162 else if (IS_KEY(v->pending, KEY_RSFT)) temp = temp >> shift ;
1164 dval = setbool((BOOLEAN)temp) ;
1165 mpcdm(&dval, v->MPdisp_val) ;
1166 show_display(v->MPdisp_val) ;
1167 mpstr(v->MPdisp_val, v->MPlast_input) ;
1173 do_sto_rcl() /* Save/restore value to/from memory register. */
1175 int i, MPn[MP_SIZE], n ;
1177 for (i = MEM_START; i <= MEM_END; i++)
1178 if (v->current == menu_entries[i].val)
1180 if (IS_KEY(v->pending, KEY_RCL)) /* Rcl */
1182 mpstr(v->MPmvals[char_val(v->current)], v->MPdisp_val) ;
1185 else if (IS_KEY(v->pending, KEY_STO)) /* Sto */
1187 n = char_val(v->current) ;
1189 if (IS_KEY(v->pending_op, KEY_ADD)) /* + */
1191 mpstr(v->MPmvals[n], MPn) ;
1192 mpadd(MPn, v->MPdisp_val, v->MPmvals[n]) ;
1194 else if (IS_KEY(v->pending_op, KEY_SUB)) /* - */
1196 mpstr(v->MPmvals[n], MPn) ;
1197 mpsub(MPn, v->MPdisp_val, v->MPmvals[n]) ;
1199 else if (IS_KEY(v->pending_op, KEY_MUL)) /* x */
1201 mpstr(v->MPmvals[n], MPn) ;
1202 mpmul(MPn, v->MPdisp_val, v->MPmvals[n]) ;
1204 else if (IS_KEY(v->pending_op, KEY_DIV)) /* / */
1206 mpstr(v->MPmvals[n], MPn) ;
1207 mpdiv(MPn, v->MPdisp_val, v->MPmvals[n]) ;
1209 else mpstr(v->MPdisp_val, v->MPmvals[n]) ;
1212 make_registers(MEM) ;
1217 if (IS_KEY(v->current, KEY_ADD) || IS_KEY(v->current, KEY_SUB) ||
1218 IS_KEY(v->current, KEY_MUL) || IS_KEY(v->current, KEY_DIV))
1219 v->pending_op = v->current ;
1224 do_trig() /* Perform all trigonometric functions. */
1226 int i, MPtemp[MP_SIZE], MP1[MP_SIZE], MP2[MP_SIZE] ;
1228 int MPcos[MP_SIZE], MPsin[MP_SIZE] ;
1234 if (v->ttype == DEG)
1237 mpmul(v->MPdisp_val, MP1, MP2) ;
1240 mpdiv(MP2, MP1, MPtemp) ;
1242 else if (v->ttype == GRAD)
1245 mpmul(v->MPdisp_val, MP1, MP2) ;
1248 mpdiv(MP2, MP1, MPtemp) ;
1250 else mpstr(v->MPdisp_val, MPtemp) ;
1252 else mpstr(v->MPdisp_val, MPtemp) ;
1256 if (IS_KEY(v->current, KEY_COS)) /* Cos */
1257 mpcos(MPtemp, v->MPtresults[(int) RAD]) ;
1258 else if (IS_KEY(v->current, KEY_SIN)) /* Sin */
1259 mpsin(MPtemp, v->MPtresults[(int) RAD]) ;
1260 else if (IS_KEY(v->current, KEY_TAN)) /* Tan */
1262 mpsin(MPtemp, MPsin) ;
1263 mpcos(MPtemp, MPcos) ;
1264 mpcmd(MPcos, &cval) ;
1265 if (cval == 0.0) doerr(vstrs[(int) V_ERROR]) ;
1266 mpdiv(MPsin, MPcos, v->MPtresults[(int) RAD]) ;
1271 if (IS_KEY(v->current, KEY_COS)) /* Cosh */
1272 mpcosh(MPtemp, v->MPtresults[(int) RAD]) ;
1273 else if (IS_KEY(v->current, KEY_SIN)) /* Sinh */
1274 mpsinh(MPtemp, v->MPtresults[(int) RAD]) ;
1275 else if (IS_KEY(v->current, KEY_TAN)) /* Tanh */
1276 mptanh(MPtemp, v->MPtresults[(int) RAD]) ;
1279 mpstr(v->MPtresults[(int) RAD], v->MPtresults[(int) DEG]) ;
1280 mpstr(v->MPtresults[(int) RAD], v->MPtresults[(int) GRAD]) ;
1286 if (IS_KEY(v->current, KEY_COS)) /* Acos */
1287 mpacos(v->MPdisp_val, v->MPdisp_val) ;
1288 else if (IS_KEY(v->current, KEY_SIN)) /* Asin */
1289 mpasin(v->MPdisp_val, v->MPdisp_val) ;
1290 else if (IS_KEY(v->current, KEY_TAN)) /* Atan */
1291 mpatan(v->MPdisp_val, v->MPdisp_val) ;
1295 if (IS_KEY(v->current, KEY_COS)) /* Acosh */
1296 mpacosh(v->MPdisp_val, v->MPdisp_val) ;
1297 else if (IS_KEY(v->current, KEY_SIN)) /* Asinh */
1298 mpasinh(v->MPdisp_val, v->MPdisp_val) ;
1299 else if (IS_KEY(v->current, KEY_TAN)) /* Atanh */
1300 mpatanh(v->MPdisp_val, v->MPdisp_val) ;
1307 mpmul(v->MPdisp_val, MP1, MP2) ;
1309 mpdiv(MP2, MP1, v->MPtresults[(int) DEG]) ;
1313 mpmul(v->MPdisp_val, MP1, MP2) ;
1315 mpdiv(MP2, MP1, v->MPtresults[(int) GRAD]) ;
1319 mpstr(v->MPdisp_val, v->MPtresults[(int) DEG]) ;
1320 mpstr(v->MPdisp_val, v->MPtresults[(int) GRAD]) ;
1323 mpstr(v->MPdisp_val, v->MPtresults[(int) RAD]) ;
1326 show_display(v->MPtresults[(int) v->ttype]) ;
1327 mpstr(v->MPtresults[(int) v->ttype], v->MPdisp_val) ;
1333 do_trigtype() /* Change the current trigonometric type. */
1335 if (v->current == TRIG_DEG) v->ttype = DEG ;
1336 else if (v->current == TRIG_GRA) v->ttype = GRAD ;
1337 else if (v->current == TRIG_RAD) v->ttype = RAD ;
1340 if (IS_KEY(v->cur_op, KEY_COS) ||
1341 IS_KEY(v->cur_op, KEY_SIN) ||
1342 IS_KEY(v->cur_op, KEY_TAN))
1344 mpstr(v->MPtresults[(int) v->ttype], v->MPdisp_val) ;
1345 show_display(v->MPtresults[(int) v->ttype]) ;
1347 set_option_menu((int) TTYPEITEM, (int)v->ttype);
1358 if (x > 68719476736.00) return(0) ;
1359 else if (x < -68719476736.00) return(0) ;
1362 while (x < 0.0) x += 4294967296.00 ;
1363 while (x >= 4294967296.00) x -= 4294967296.00 ;
1375 if (x > 9007199254740991.00 || x < -9007199254740991.00)
1381 while (x < 0.0) x += 4294967296.00 ;
1382 while (x >= 4294967296.00) x -= 4294967296.00 ;
1389 /* The following MP routines were not in the Brent FORTRAN package. They are
1390 * derived here, in terms of the existing routines.
1393 /* MP precision arc cosine.
1395 * 1. If (x < -1.0 or x > 1.0) then report DOMAIN error and return 0.0.
1397 * 2. If (x = 0.0) then acos(x) = PI/2.
1399 * 3. If (x = 1.0) then acos(x) = 0.0
1401 * 4. If (x = -1.0) then acos(x) = PI.
1403 * 5. If (0.0 < x < 1.0) then acos(x) = atan(sqrt(1-(x**2)) / x)
1405 * 6. If (-1.0 < x < 0.0) then acos(x) = atan(sqrt(1-(x**2)) / x) + PI
1409 mpacos(MPx, MPretval)
1410 int *MPx, *MPretval ;
1412 int MP0[MP_SIZE], MP1[MP_SIZE], MP2[MP_SIZE] ;
1413 int MPn1[MP_SIZE], MPpi[MP_SIZE], MPy[MP_SIZE], val ;
1423 if (mpgt(MPx, MP1) || mplt(MPx, MPn1))
1425 doerr("acos DOMAIN error") ;
1426 mpstr(MP0, MPretval) ;
1428 else if (mpeq(MPx, MP0))
1431 mpdivi(MPpi, &val, MPretval) ;
1433 else if (mpeq(MPx, MP1)) mpstr(MP0, MPretval) ;
1434 else if (mpeq(MPx, MPn1)) mpstr(MPpi, MPretval) ;
1437 mpmul(MPx, MPx, MP2) ;
1438 mpsub(MP1, MP2, MP2) ;
1440 mpdiv(MP2, MPx, MP2) ;
1442 if (mpgt(MPx, MP0)) mpstr(MPy, MPretval) ;
1443 else mpadd(MPy, MPpi, MPretval) ;
1448 /* MP precision hyperbolic arc cosine.
1450 * 1. If (x < 1.0) then report DOMAIN error and return 0.0.
1452 * 2. acosh(x) = log(x + sqrt(x**2 - 1))
1456 mpacosh(MPx, MPretval)
1457 int *MPx, *MPretval ;
1459 int MP1[MP_SIZE], val ;
1465 doerr("acosh DOMAIN error") ;
1467 mpcim(&val, MPretval) ;
1471 mpmul(MPx, MPx, MP1) ;
1473 mpaddi(MP1, &val, MP1) ;
1475 mpadd(MPx, MP1, MP1) ;
1476 mpln(MP1, MPretval) ;
1481 /* MP precision hyperbolic arc sine.
1483 * 1. asinh(x) = log(x + sqrt(x**2 + 1))
1487 mpasinh(MPx, MPretval)
1488 int *MPx, *MPretval ;
1490 int MP1[MP_SIZE], val ;
1492 mpmul(MPx, MPx, MP1) ;
1494 mpaddi(MP1, &val, MP1) ;
1496 mpadd(MPx, MP1, MP1) ;
1497 mpln(MP1, MPretval) ;
1501 /* MP precision hyperbolic arc tangent.
1503 * 1. If (x <= -1.0 or x >= 1.0) then report a DOMAIn error and return 0.0.
1505 * 2. atanh(x) = 0.5 * log((1 + x) / (1 - x))
1509 mpatanh(MPx, MPretval)
1510 int *MPx, *MPretval ;
1512 int MP0[MP_SIZE], MP1[MP_SIZE], MP2[MP_SIZE] ;
1513 int MP3[MP_SIZE], MPn1[MP_SIZE], val ;
1522 if (mpge(MPx, MP1) || mple(MPx, MPn1))
1524 doerr("atanh DOMAIN error") ;
1525 mpstr(MP0, MPretval) ;
1529 mpadd(MP1, MPx, MP2) ;
1530 mpsub(MP1, MPx, MP3) ;
1531 mpdiv(MP2, MP3, MP3) ;
1533 MPstr_to_num("0.5", DEC, MP1) ;
1534 mpmul(MP1, MP3, MPretval) ;
1539 /* MP precision common log.
1541 * 1. log10(x) = log10(e) * log(x)
1545 mplog10(MPx, MPretval)
1546 int *MPx, *MPretval ;
1548 int MP1[MP_SIZE], MP2[MP_SIZE], n ;
1554 mpdiv(MP2, MP1, MPretval) ;
1559 process_parens(current)
1563 int last_lpar ; /* Position in stack of last left paren. */
1564 int last_num ; /* Position is numeric stack to start processing. */
1566 /* Check to see if this is the first outstanding parenthesis. If so, and
1567 * their is a current operation already defined, then push the current
1568 * result on the numeric stack, and note it on the op stack, with a -1,
1569 * which has this special significance.
1570 * Zeroise current display value (in case of invalid operands inside the
1572 * Add the current pending operation to the opstack.
1573 * Increment parentheses count.
1576 if (IS_KEY(current, KEY_LPAR))
1578 if (!v->noparens && v->cur_op != '?')
1580 push_num(v->MPresult) ;
1583 mpcim(&i, v->MPdisp_val) ;
1584 push_op(v->cur_op) ;
1586 v->noparens++ ; /* Count of left brackets outstanding. */
1587 save_pending_values(current) ;
1590 /* If we haven't had any left brackets yet, and this is a right bracket,
1591 * then just ignore it.
1592 * Decrement the bracket count.
1593 * Add a equals to the op stack, to force a calculation to be performed
1594 * for two op operands. This is ignored if the preceding element of the
1595 * op stack was an immediate operation.
1596 * Work out where the preceding left bracket is in the stack, and then
1597 * process the stack from that point until this end, pushing the result
1598 * on the numeric stack, and setting the new op stack pointer appropriately.
1599 * If there are no brackets left unmatched, then clear the pending flag,
1600 * clear the stack pointers and current operation, and show the display.
1603 else if (IS_KEY(current, KEY_RPAR))
1607 last_lpar = v->opsptr - 1 ;
1608 last_num = v->numsptr ;
1609 while (!IS_KEY(v->opstack[last_lpar], KEY_LPAR))
1611 if (v->opstack[last_lpar] == -1) last_num-- ;
1614 process_stack(last_lpar + 1, last_num, v->opsptr - last_lpar - 1) ;
1620 process_stack(0, 0, v->opsptr) ;
1622 v->pending = v->opsptr = v->numsptr = 0 ;
1624 set_item(OPITEM, "") ;
1627 set_item(DISPLAYITEM, vstrs[(int) V_ERROR]) ;
1628 set_item(OPITEM, vstrs[(int) V_CLR]) ;
1629 STRCPY(v->display, vstrs[(int) V_ERROR]) ;
1633 show_display(v->MPdisp_val) ;
1634 mpstr(v->MPdisp_val, v->MPlast_input) ;
1644 push_num(MPval) /* Try to push value onto the numeric stack. */
1647 if (v->numsptr < 0) return ;
1648 if (v->numsptr >= MAXSTACK)
1650 STRCPY(v->display, vstrs[(int) V_NUMSTACK]) ;
1651 set_item(DISPLAYITEM, v->display) ;
1654 set_item(OPITEM, vstrs[(int) V_CLR]) ;
1658 if (v->MPnumstack[v->numsptr] == NULL)
1659 v->MPnumstack[v->numsptr] =
1660 (int *) LINT_CAST(calloc(1, sizeof(int) * MP_SIZE)) ;
1661 mpstr(MPval, v->MPnumstack[v->numsptr++]) ;
1667 push_op(val) /* Try to push value onto the operand stack. */
1670 if (v->opsptr < 0) return ;
1671 if (v->opsptr >= MAXSTACK)
1673 STRCPY(v->display, vstrs[(int) V_OPSTACK]) ;
1674 set_item(DISPLAYITEM, v->display) ;
1676 set_item(OPITEM, vstrs[(int) V_CLR]) ;
1678 else v->opstack[v->opsptr++] = val ;
1683 save_pending_values(val)
1689 for (n = 0; n < TITEMS; n++)
1691 if (val == buttons[n].value)
1694 v->pending_win = v->curwin ;
1695 if (v->pending_win == FCP_MODE)
1696 v->pending_mode = v->modetype ;
1707 q = p & 0x80000000 ;
1710 if (q) val += 2147483648.0 ;
1715 do_round(result, ndigits)
1719 char buf2[40], buffer[100];
1722 if (isnan(result)) return result;
1723 #if defined(_AIX) || defined(__aix) || defined(__osf__)
1724 temp = finite(result);
1726 return (temp > 0) ? HUGE : -HUGE;
1728 #if defined(USL) || defined(__uxp__)
1729 temp = finite(result);
1731 return (temp > 0) ? HUGE : -HUGE;
1733 if (temp = isinf(result)) return (temp > 0) ? HUGE : -HUGE;
1734 #endif /* USL or __uxp__ */
1735 #endif /* _AIX or __osf__ */
1737 if (ndigits >= 0 && ndigits < MAX_DIGITS)
1739 result += 0.5 * (result > 0 ? mods[ndigits] : -mods[ndigits]);
1740 result -= fmod(result, mods[ndigits]);
1743 sprintf(buf2, "%%.%dlg", MAX_DIGITS);
1744 sprintf(buffer, buf2, result);
1745 return atof(buffer);
1749 try_compute_i(guess, result, method)
1754 double sum_pos, sum_pos_prime, sum_neg, sum_neg_prime, w = guess;
1760 double term, term_prime, f, f_prime, lsp, lsn;
1762 sum_pos = sum_pos_prime = sum_neg = sum_neg_prime = 0;
1764 if (v->MPfvals[2] != 0.0)
1769 term_prime = v->MPfvals[0];
1773 term = pow(w, v->MPfvals[0]);
1774 term_prime = (v->MPfvals[0]) * pow(w, v->MPfvals[0] - 1.0);
1776 if (v->MPfvals[2] > 0.0)
1778 sum_pos += v->MPfvals[2] * term;
1779 sum_pos_prime += v->MPfvals[2] * term_prime;
1783 sum_neg -= v->MPfvals[2] * term;
1784 sum_neg_prime -= v->MPfvals[2] * term_prime;
1787 if (v->MPfvals[3] != 0.0)
1791 term = v->MPfvals[0];
1793 term_prime = v->MPfvals[0] * (v->MPfvals[0] - 1) / 2.0 +
1794 v->MPfvals[0] * (0.0);
1798 double wn = pow(w, v->MPfvals[0]);
1799 double wdb = pow(w, 0.0);
1801 term = (wn - 1.0) * wdb / (w - 1.0);
1803 term_prime = (v->MPfvals[0] * pow(w,(0.0 + v->MPfvals[0] - .01))
1804 + (wn - 1.0) * (0.0) * pow(w, (0.0 - 1.0))) /
1805 (w - 1.0) - (wn - 1.0) * wdb /
1806 ((w - 1.0) * (w - 1.0));
1809 if (v->MPfvals[3] > 0.0)
1811 sum_pos += v->MPfvals[3] * term;
1812 sum_pos_prime += v->MPfvals[3] * term_prime;
1816 sum_neg -= v->MPfvals[3] * term;
1817 sum_neg_prime -= v->MPfvals[3] * term_prime;
1820 if (v->MPfvals[4] != 0.0)
1822 if (v->MPfvals[4] > 0.0) sum_pos += v->MPfvals[4];
1823 else sum_neg -= v->MPfvals[4];
1833 f_prime = sum_pos_prime / sum_pos - sum_neg_prime / sum_neg;
1836 f = lsp / lsn - 1.0;
1837 f_prime = (lsn * sum_pos_prime / sum_pos -
1838 lsp * sum_neg_prime / sum_neg) /
1843 new_w = w - f / f_prime;
1845 #if defined(_AIX) || defined(__aix) || defined (__osf__)
1846 if (!(!isnan(new_w) && finite(new_w)))
1849 #if defined(USL) || defined(__uxp__)
1850 if (!(!isnan(new_w) && finite(new_w)))
1853 if (!(!isnan(new_w) && !isinf(new_w)))
1856 #endif /* _AIX or __osf__ */
1858 if (new_w == w || w != 0.0 && fabs((new_w - w) / w) < FIN_EPSILON)
1863 if (niter++ >= MAX_FIN_ITER)
1867 *result = do_round((new_w - 1.0) * 100.0 * v->MPfvals[5], -1);
1875 double first_period, last_period;
1882 if (first_period < 0.0 || last_period < 0.0)
1884 doerr(GETMESSAGE(5, 5, "ERROR:Invalid odd period values"));
1888 p[0] = v->MPfvals[2] + (first_period == 0.0 ? v->MPfvals[3] : 0);
1889 p[1] = v->MPfvals[3];
1890 p[2] = v->MPfvals[4] + (last_period == 0.0 ? v->MPfvals[3] : 0);
1892 nsc = count_sign_changes(p, 3);
1896 int MP1[MP_SIZE], MP2[MP_SIZE], MP3[MP_SIZE], MP4[MP_SIZE];
1901 temp = v->MPfvals[4]/v->MPfvals[2];
1905 mpcdm(&(v->MPfvals[0]), MP4);
1906 mpdiv(MP2, MP4, MP3) ;
1907 mppwr2(MP1, MP3, MP5) ;
1909 mpaddi(MP5, &val, MP1) ;
1911 mpmuli(MP1, &val, v->MPdisp_val) ;
1912 mpcmd(v->MPdisp_val, target);
1917 doerr(GETMESSAGE(5, 3, "ERROR: Multiple Solutions"));
1920 else if (v->MPfvals[0] <= 0)
1922 doerr(GETMESSAGE(5, 4, "ERROR: Term <= 0"));
1926 success = try_compute_i((double)1.0, target, 1);
1927 success = success || try_compute_i((double)1.0e-12, target, 1);
1928 success = success || try_compute_i((double)1.0, target, 2);
1929 success = success || try_compute_i((double)1.0e-12, target, 2);
1932 doerr(GETMESSAGE(5, 1, "ERROR: Computation Failed"));
1936 count_sign_changes(cf, count)
1940 int i, curr_sign = 0, result = 0;
1942 for (i = 0; i < count; i++)
1944 if (cf[i] == 0.0) continue;
1948 if (cf[i] > 0.0) continue;
1952 else if (curr_sign == -1)
1954 if (cf[i] < 0.0) continue;
1960 if (cf[i] > 0.0) curr_sign = 1;
1961 else curr_sign = -1;