2 /* Copyright (c) 1987-2007 Sun Microsystems, Inc. All Rights Reserved.
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
26 #include "display.h" /* FIXME: Needed to MPstr_to_num() */
31 BOOLEAN p
= (BOOLEAN
) x
;
55 calc_and(int t
[MP_SIZE
], int s1
[MP_SIZE
], int s2
[MP_SIZE
])
61 dres
= setbool(ibool(dres
) & ibool(dval
));
67 calc_or(int t
[MP_SIZE
], int s1
[MP_SIZE
], int s2
[MP_SIZE
])
73 dres
= setbool(ibool(dres
) | ibool(dval
));
79 calc_xor(int t
[MP_SIZE
], int s1
[MP_SIZE
], int s2
[MP_SIZE
])
85 dres
= setbool(ibool(dres
) ^ ibool(dval
));
91 calc_xnor(int t
[MP_SIZE
], int s1
[MP_SIZE
], int s2
[MP_SIZE
])
97 dres
= setbool(~ibool(dres
) ^ ibool(dval
));
103 calc_not(int s1
[MP_SIZE
], int t
[MP_SIZE
])
108 dval
= setbool(~ibool(dval
));
114 calc_rand(int t
[MP_SIZE
])
116 double dval
= drand48();
123 calc_u32(int s1
[MP_SIZE
], int t1
[MP_SIZE
])
128 dval
= setbool(ibool(dval
));
134 calc_u16(int s1
[MP_SIZE
], int t1
[MP_SIZE
])
139 dval
= setbool(ibool(dval
) & 0xffff);
145 calc_inv(int s1
[MP_SIZE
], int t1
[MP_SIZE
]) /* Calculate 1/x */
158 calc_tenpowx(int s1
[MP_SIZE
], int t1
[MP_SIZE
]) /* Calculate 10^x */
169 calc_xpowy(int MPx
[MP_SIZE
], int MPy
[MP_SIZE
], int MPres
[MP_SIZE
]) /* Do x^y */
171 int MP0
[MP_SIZE
], val
;
176 /* Check if both x and y are zero. If yes, then just return 1.
177 * See gcalctool bug #451286.
179 if (mpeq(MPx
, MP0
) && mpeq(MPy
, MP0
)) {
183 } else if (mplt(MPx
, MP0
)) { /* Is x < 0 ? */
187 if (mpeq(MPtmp
, MPy
)) { /* Is y == int(y) ? */
191 mppwr(MPx
, &y
, MPres
);
192 } else { /* y != int(y). Force mppwr2 to generate an error. */
193 mppwr2(MPx
, MPy
, MPres
);
196 mppwr2(MPx
, MPy
, MPres
);
202 calc_xtimestenpowx(int s1
[MP_SIZE
], int s2
[MP_SIZE
], int t1
[MP_SIZE
])
206 calc_tenpowx(s2
, MP1
);
211 calc_modulus(int op1
[MP_SIZE
],
215 int MP1
[MP_SIZE
], MP2
[MP_SIZE
];
219 if (!mpeq(op1
, MP1
) || !mpeq(op2
, MP2
)) {
223 mpdiv(op1
, op2
, MP1
);
225 mpmul(MP1
, op2
, MP2
);
226 mpsub(op1
, MP2
, result
);
231 calc_percent(int s1
[MP_SIZE
], int t1
[MP_SIZE
])
235 MPstr_to_num("0.01", DEC
, MP1
);
240 do_zero(int t1
[MP_SIZE
])
249 do_e(int t1
[MP_SIZE
])
251 double e
= 2.71828182846;
258 mptan(int s1
[MP_SIZE
], int t1
[MP_SIZE
])
268 doerr(_("Error, cannot calculate cosine"));
270 mpdiv(MPsin
, MPcos
, t1
);
274 /* Change type to radian */
277 to_rad(int s1
[MP_SIZE
], int t1
[MP_SIZE
])
279 int i
, MP1
[MP_SIZE
], MP2
[MP_SIZE
];
281 if (v
->ttype
== DEG
) {
287 } else if (v
->ttype
== GRAD
) {
300 do_trig_typeconv(enum trig_type ttype
, int s1
[MP_SIZE
], int t1
[MP_SIZE
])
302 int i
, MP1
[MP_SIZE
], MP2
[MP_SIZE
];
333 /* The following MP routines were not in the Brent FORTRAN package. They are
334 * derived here, in terms of the existing routines.
337 /* MP precision arc cosine.
339 * 1. If (x < -1.0 or x > 1.0) then report DOMAIN error and return 0.0.
341 * 2. If (x = 0.0) then acos(x) = PI/2.
343 * 3. If (x = 1.0) then acos(x) = 0.0
345 * 4. If (x = -1.0) then acos(x) = PI.
347 * 5. If (0.0 < x < 1.0) then acos(x) = atan(sqrt(1-(x**2)) / x)
349 * 6. If (-1.0 < x < 0.0) then acos(x) = atan(sqrt(1-(x**2)) / x) + PI
353 mpacos(int *MPx
, int *MPretval
)
355 int MP0
[MP_SIZE
], MP1
[MP_SIZE
], MP2
[MP_SIZE
];
356 int MPn1
[MP_SIZE
], MPpi
[MP_SIZE
], MPy
[MP_SIZE
], val
;
366 if (mpgt(MPx
, MP1
) || mplt(MPx
, MPn1
)) {
368 mpstr(MP0
, MPretval
);
369 } else if (mpeq(MPx
, MP0
)) {
371 mpdivi(MPpi
, &val
, MPretval
);
372 } else if (mpeq(MPx
, MP1
)) {
373 mpstr(MP0
, MPretval
);
374 } else if (mpeq(MPx
, MPn1
)) {
375 mpstr(MPpi
, MPretval
);
377 mpmul(MPx
, MPx
, MP2
);
378 mpsub(MP1
, MP2
, MP2
);
380 mpdiv(MP2
, MPx
, MP2
);
382 if (mpgt(MPx
, MP0
)) {
383 mpstr(MPy
, MPretval
);
385 mpadd(MPy
, MPpi
, MPretval
);
391 /* MP precision hyperbolic arc cosine.
393 * 1. If (x < 1.0) then report DOMAIN error and return 0.0.
395 * 2. acosh(x) = log(x + sqrt(x**2 - 1))
399 mpacosh(int *MPx
, int *MPretval
)
401 int MP1
[MP_SIZE
], val
;
405 if (mplt(MPx
, MP1
)) {
408 mpcim(&val
, MPretval
);
410 mpmul(MPx
, MPx
, MP1
);
412 mpaddi(MP1
, &val
, MP1
);
414 mpadd(MPx
, MP1
, MP1
);
420 /* MP precision hyperbolic arc sine.
422 * 1. asinh(x) = log(x + sqrt(x**2 + 1))
426 mpasinh(int *MPx
, int *MPretval
)
428 int MP1
[MP_SIZE
], val
;
430 mpmul(MPx
, MPx
, MP1
);
432 mpaddi(MP1
, &val
, MP1
);
434 mpadd(MPx
, MP1
, MP1
);
439 /* MP precision hyperbolic arc tangent.
441 * 1. If (x <= -1.0 or x >= 1.0) then report a DOMAIn error and return 0.0.
443 * 2. atanh(x) = 0.5 * log((1 + x) / (1 - x))
447 mpatanh(int *MPx
, int *MPretval
)
449 int MP0
[MP_SIZE
], MP1
[MP_SIZE
], MP2
[MP_SIZE
];
450 int MP3
[MP_SIZE
], MPn1
[MP_SIZE
];
460 if (mpge(MPx
, MP1
) || mple(MPx
, MPn1
)) {
462 mpstr(MP0
, MPretval
);
464 mpadd(MP1
, MPx
, MP2
);
465 mpsub(MP1
, MPx
, MP3
);
466 mpdiv(MP2
, MP3
, MP3
);
468 MPstr_to_num("0.5", DEC
, MP1
);
469 mpmul(MP1
, MP3
, MPretval
);
474 /* MP precision common log.
476 * 1. log10(x) = log10(e) * log(x)
480 mplog10(int *MPx
, int *MPretval
)
482 int MP1
[MP_SIZE
], MP2
[MP_SIZE
], n
;
488 mpdiv(MP2
, MP1
, MPretval
);
493 calc_ctrm(int t
[MP_SIZE
])
496 /* Cterm - MEM0 = int (periodic interest rate).
497 * MEM1 = fv (future value).
498 * MEM2 = pv (present value).
500 * RESULT = log(MEM1 / MEM2) / log(1 + MEM0)
504 int MP1
[MP_SIZE
], MP2
[MP_SIZE
], MP3
[MP_SIZE
], MP4
[MP_SIZE
];
506 mpdiv(v
->MPmvals
[1], v
->MPmvals
[2], MP1
);
509 mpaddi(v
->MPmvals
[0], &val
, MP3
);
516 calc_ddb(int t
[MP_SIZE
])
519 /* Ddb - MEM0 = cost (amount paid for asset).
520 * MEM1 = salvage (value of asset at end of its life).
521 * MEM2 = life (useful life of the asset).
522 * MEM3 = period (time period for depreciation allowance).
525 * for (i = 0; i < MEM3; i++)
527 * VAL = ((MEM0 - bv) * 2) / MEM2
536 int MPbv
[MP_SIZE
], MP1
[MP_SIZE
], MP2
[MP_SIZE
];
540 mpcmi(v
->MPmvals
[3], &len
);
541 for (i
= 0; i
< len
; i
++) {
542 mpsub(v
->MPmvals
[0], MPbv
, MP1
);
544 mpmuli(MP1
, &val
, MP2
);
545 mpdiv(MP2
, v
->MPmvals
[2], t
);
547 mpadd(MP1
, t
, MPbv
); /* TODO: why result is MPbv, for next loop? */
553 calc_fv(int t
[MP_SIZE
])
556 /* Fv - MEM0 = pmt (periodic payment).
557 * MEM1 = int (periodic interest rate).
558 * MEM2 = n (number of periods).
560 * RESULT = MEM0 * (pow(1 + MEM1, MEM2) - 1) / MEM1
564 int MP1
[MP_SIZE
], MP2
[MP_SIZE
], MP3
[MP_SIZE
], MP4
[MP_SIZE
];
567 mpaddi(v
->MPmvals
[1], &val
, MP1
);
568 mppwr2(MP1
, v
->MPmvals
[2], MP2
);
570 mpaddi(MP2
, &val
, MP3
);
571 mpmul(v
->MPmvals
[0], MP3
, MP4
);
572 mpdiv(MP4
, v
->MPmvals
[1], t
);
577 calc_pmt(int t
[MP_SIZE
])
580 /* Pmt - MEM0 = prin (principal).
581 * MEM1 = int (periodic interest rate).
584 * RESULT = MEM0 * (MEM1 / (1 - pow(MEM1 + 1, -1 * MEM2)))
588 int MP1
[MP_SIZE
], MP2
[MP_SIZE
], MP3
[MP_SIZE
], MP4
[MP_SIZE
];
591 mpaddi(v
->MPmvals
[1], &val
, MP1
);
593 mpmuli(v
->MPmvals
[2], &val
, MP2
);
594 mppwr2(MP1
, MP2
, MP3
);
596 mpmuli(MP3
, &val
, MP4
);
598 mpaddi(MP4
, &val
, MP1
);
599 mpdiv(v
->MPmvals
[1], MP1
, MP2
);
600 mpmul(v
->MPmvals
[0], MP2
, t
);
605 calc_pv(int t
[MP_SIZE
])
608 /* Pv - MEM0 = pmt (periodic payment).
609 * MEM1 = int (periodic interest rate).
612 * RESULT = MEM0 * (1 - pow(1 + MEM1, -1 * MEM2)) / MEM1
616 int MP1
[MP_SIZE
], MP2
[MP_SIZE
], MP3
[MP_SIZE
], MP4
[MP_SIZE
];
619 mpaddi(v
->MPmvals
[1], &val
, MP1
);
621 mpmuli(v
->MPmvals
[2], &val
, MP2
);
622 mppwr2(MP1
, MP2
, MP3
);
624 mpmuli(MP3
, &val
, MP4
);
626 mpaddi(MP4
, &val
, MP1
);
627 mpdiv(MP1
, v
->MPmvals
[1], MP2
);
628 mpmul(v
->MPmvals
[0], MP2
, t
);
633 calc_rate(int t
[MP_SIZE
])
636 /* Rate - MEM0 = fv (future value).
637 * MEM1 = pv (present value).
640 * RESULT = pow(MEM0 / MEM1, 1 / MEM2) - 1
644 int MP1
[MP_SIZE
], MP2
[MP_SIZE
], MP3
[MP_SIZE
], MP4
[MP_SIZE
];
646 mpdiv(v
->MPmvals
[0], v
->MPmvals
[1], MP1
);
649 mpdiv(MP2
, v
->MPmvals
[2], MP3
);
650 mppwr2(MP1
, MP3
, MP4
);
652 mpaddi(MP4
, &val
, t
);
657 calc_sln(int t
[MP_SIZE
])
660 /* Sln - MEM0 = cost (cost of the asset).
661 * MEM1 = salvage (salvage value of the asset).
662 * MEM2 = life (useful life of the asset).
664 * RESULT = (MEM0 - MEM1) / MEM2
669 mpsub(v
->MPmvals
[0], v
->MPmvals
[1], MP1
);
670 mpdiv(MP1
, v
->MPmvals
[2], t
);
675 calc_syd(int t
[MP_SIZE
])
678 /* Syd - MEM0 = cost (cost of the asset).
679 * MEM1 = salvage (salvage value of the asset).
680 * MEM2 = life (useful life of the asset).
681 * MEM3 = period (period for which depreciation is computed).
683 * RESULT = ((MEM0 - MEM1) * (MEM2 - MEM3 + 1)) /
684 * (MEM2 * (MEM2 + 1) / 2)
688 int MP1
[MP_SIZE
], MP2
[MP_SIZE
], MP3
[MP_SIZE
], MP4
[MP_SIZE
];
690 mpsub(v
->MPmvals
[2], v
->MPmvals
[3], MP2
);
692 mpaddi(MP2
, &val
, MP3
);
693 mpaddi(v
->MPmvals
[2], &val
, MP2
);
694 mpmul(v
->MPmvals
[2], MP2
, MP4
);
697 mpdiv(MP4
, MP2
, MP1
);
698 mpdiv(MP3
, MP1
, MP2
);
699 mpsub(v
->MPmvals
[0], v
->MPmvals
[1], MP1
);
705 calc_term(int t
[MP_SIZE
])
708 /* Term - MEM0 = pmt (periodic payment).
709 * MEM1 = fv (future value).
710 * MEM2 = int (periodic interest rate).
712 * RESULT = log(1 + (MEM1 * MEM2 / MEM0)) / log(1 + MEM2)
716 int MP1
[MP_SIZE
], MP2
[MP_SIZE
], MP3
[MP_SIZE
], MP4
[MP_SIZE
];
719 mpaddi(v
->MPmvals
[2], &val
, MP1
);
721 mpmul(v
->MPmvals
[1], v
->MPmvals
[2], MP1
);
722 mpdiv(MP1
, v
->MPmvals
[0], MP3
);
724 mpaddi(MP3
, &val
, MP4
);
731 calc_shift(int s
[MP_SIZE
], int t
[MP_SIZE
], int times
)
733 /* Implementation derived from old code.
734 * Using BOOLEAN is strange at least. Assumed that
735 * boolean means BINARY representation
743 /* There is a reason to do shift like this. Reason is that
744 * processors define shift only in a certain range. i386 uses only 5
745 * bits to describe shiftable amount. So, shift 32 times gives original
746 * number. That can cause very strange results (and bugs).
760 dval
= setbool(temp
);
766 is_integer(int MPnum
[MP_SIZE
])
769 int MPtt
[MP_SIZE
], MP0
[MP_SIZE
], MP1
[MP_SIZE
];
771 /* Multiplication and division by 10000 is used to get around a
772 * limitation to the "fix" for Sun bugtraq bug #4006391 in the
773 * mpcmim() routine in mp.c, when the exponent is less than 1.
776 mpmul(MPnum
, MPtt
, MP0
);
777 mpdiv(MP0
, MPtt
, MP0
);
780 return mpeq(MP0
, MP1
);
785 is_natural(int MPnum
[MP_SIZE
])
788 if (!is_integer(MPnum
)) {
792 return mpeq(MPnum
, MP1
);
796 calc_epowy(int s
[MP_SIZE
], int t
[MP_SIZE
])
804 /* Calculate selected trigonometric function */
807 calc_trigfunc(enum trigfunc_type type
, int s1
[MP_SIZE
], int t1
[MP_SIZE
])
839 do_trig_typeconv(v
->ttype
, t1
, t1
);
844 do_trig_typeconv(v
->ttype
, t1
, t1
);
849 do_trig_typeconv(v
->ttype
, t1
, t1
);