2 /* Copyright (c) 1987-2006 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
23 #include "calctool.h" /* FIXME: include only needed stuff. */
27 static void mpacos(int *, int *);
28 static void mpacosh(int *, int *);
29 static void mpasinh(int *, int *);
30 static void mpatanh(int *, int *);
36 BOOLEAN p
= (BOOLEAN
) x
;
60 calc_and(int t
[MP_SIZE
], int s1
[MP_SIZE
], int s2
[MP_SIZE
])
66 dres
= setbool(ibool(dres
) & ibool(dval
));
72 calc_or(int t
[MP_SIZE
], int s1
[MP_SIZE
], int s2
[MP_SIZE
])
78 dres
= setbool(ibool(dres
) | ibool(dval
));
84 calc_xor(int t
[MP_SIZE
], int s1
[MP_SIZE
], int s2
[MP_SIZE
])
90 dres
= setbool(ibool(dres
) ^ ibool(dval
));
96 calc_xnor(int t
[MP_SIZE
], int s1
[MP_SIZE
], int s2
[MP_SIZE
])
102 dres
= setbool(~ibool(dres
) ^ ibool(dval
));
108 calc_not(int s1
[MP_SIZE
], int t
[MP_SIZE
])
113 dval
= setbool(~ibool(dval
));
119 calc_rand(int t
[MP_SIZE
])
121 double dval
= drand48();
128 calc_u32(int s1
[MP_SIZE
], int t1
[MP_SIZE
])
133 dval
= setbool(ibool(dval
));
139 calc_u16(int s1
[MP_SIZE
], int t1
[MP_SIZE
])
144 dval
= setbool(ibool(dval
) & 0xffff);
150 calc_inv(int s1
[MP_SIZE
], int t1
[MP_SIZE
]) /* Calculate 1/x */
163 calc_tenpowx(int s1
[MP_SIZE
], int t1
[MP_SIZE
]) /* Calculate 10^x */
174 calc_xpowy(int MPx
[MP_SIZE
], int MPy
[MP_SIZE
], int MPres
[MP_SIZE
]) /* Do x^y */
176 int MP0
[MP_SIZE
], val
;
180 if (mplt(MPx
, MP0
)) { /* Is x < 0 ? */
184 if (mpeq(MPtmp
, MPy
)) { /* Is y == int(y) ? */
188 mppwr(MPx
, &y
, MPres
);
189 } else { /* y != int(y). Force mppwr2 to generate an error. */
190 mppwr2(MPx
, MPy
, MPres
);
193 mppwr2(MPx
, MPy
, MPres
);
199 calc_xtimestenpowx(int s1
[MP_SIZE
], int s2
[MP_SIZE
], int t1
[MP_SIZE
])
203 calc_tenpowx(s2
, MP1
);
208 calc_modulus(int op1
[MP_SIZE
],
212 int MP1
[MP_SIZE
], MP2
[MP_SIZE
];
216 if (!mpeq(op1
, MP1
) || !mpeq(op2
, MP2
)) {
220 mpdiv(op1
, op2
, MP1
);
222 mpmul(MP1
, op2
, MP2
);
223 mpsub(op1
, MP2
, result
);
228 calc_percent(int s1
[MP_SIZE
], int s2
[MP_SIZE
], int t1
[MP_SIZE
])
234 MPstr_to_num("0.01", DEC
, MP2
);
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 /* Calculate selected trigonometric function */
336 calc_trigfunc(enum trigfunc_type type
, int s1
[MP_SIZE
], int t1
[MP_SIZE
])
368 do_trig_typeconv(v
->ttype
, t1
, t1
);
373 do_trig_typeconv(v
->ttype
, t1
, t1
);
378 do_trig_typeconv(v
->ttype
, t1
, t1
);
398 /* The following MP routines were not in the Brent FORTRAN package. They are
399 * derived here, in terms of the existing routines.
402 /* MP precision arc cosine.
404 * 1. If (x < -1.0 or x > 1.0) then report DOMAIN error and return 0.0.
406 * 2. If (x = 0.0) then acos(x) = PI/2.
408 * 3. If (x = 1.0) then acos(x) = 0.0
410 * 4. If (x = -1.0) then acos(x) = PI.
412 * 5. If (0.0 < x < 1.0) then acos(x) = atan(sqrt(1-(x**2)) / x)
414 * 6. If (-1.0 < x < 0.0) then acos(x) = atan(sqrt(1-(x**2)) / x) + PI
418 mpacos(int *MPx
, int *MPretval
)
420 int MP0
[MP_SIZE
], MP1
[MP_SIZE
], MP2
[MP_SIZE
];
421 int MPn1
[MP_SIZE
], MPpi
[MP_SIZE
], MPy
[MP_SIZE
], val
;
431 if (mpgt(MPx
, MP1
) || mplt(MPx
, MPn1
)) {
433 mpstr(MP0
, MPretval
);
434 } else if (mpeq(MPx
, MP0
)) {
436 mpdivi(MPpi
, &val
, MPretval
);
437 } else if (mpeq(MPx
, MP1
)) {
438 mpstr(MP0
, MPretval
);
439 } else if (mpeq(MPx
, MPn1
)) {
440 mpstr(MPpi
, MPretval
);
442 mpmul(MPx
, MPx
, MP2
);
443 mpsub(MP1
, MP2
, MP2
);
445 mpdiv(MP2
, MPx
, MP2
);
447 if (mpgt(MPx
, MP0
)) {
448 mpstr(MPy
, MPretval
);
450 mpadd(MPy
, MPpi
, MPretval
);
456 /* MP precision hyperbolic arc cosine.
458 * 1. If (x < 1.0) then report DOMAIN error and return 0.0.
460 * 2. acosh(x) = log(x + sqrt(x**2 - 1))
464 mpacosh(int *MPx
, int *MPretval
)
466 int MP1
[MP_SIZE
], val
;
470 if (mplt(MPx
, MP1
)) {
473 mpcim(&val
, MPretval
);
475 mpmul(MPx
, MPx
, MP1
);
477 mpaddi(MP1
, &val
, MP1
);
479 mpadd(MPx
, MP1
, MP1
);
485 /* MP precision hyperbolic arc sine.
487 * 1. asinh(x) = log(x + sqrt(x**2 + 1))
491 mpasinh(int *MPx
, int *MPretval
)
493 int MP1
[MP_SIZE
], val
;
495 mpmul(MPx
, MPx
, MP1
);
497 mpaddi(MP1
, &val
, MP1
);
499 mpadd(MPx
, MP1
, MP1
);
504 /* MP precision hyperbolic arc tangent.
506 * 1. If (x <= -1.0 or x >= 1.0) then report a DOMAIn error and return 0.0.
508 * 2. atanh(x) = 0.5 * log((1 + x) / (1 - x))
512 mpatanh(int *MPx
, int *MPretval
)
514 int MP0
[MP_SIZE
], MP1
[MP_SIZE
], MP2
[MP_SIZE
];
515 int MP3
[MP_SIZE
], MPn1
[MP_SIZE
];
525 if (mpge(MPx
, MP1
) || mple(MPx
, MPn1
)) {
527 mpstr(MP0
, MPretval
);
529 mpadd(MP1
, MPx
, MP2
);
530 mpsub(MP1
, MPx
, MP3
);
531 mpdiv(MP2
, MP3
, MP3
);
533 MPstr_to_num("0.5", DEC
, MP1
);
534 mpmul(MP1
, MP3
, MPretval
);
539 /* MP precision common log.
541 * 1. log10(x) = log10(e) * log(x)
545 mplog10(int *MPx
, int *MPretval
)
547 int MP1
[MP_SIZE
], MP2
[MP_SIZE
], n
;
553 mpdiv(MP2
, MP1
, MPretval
);
558 calc_ctrm(int t
[MP_SIZE
])
561 /* Cterm - MEM0 = int (periodic interest rate).
562 * MEM1 = fv (future value).
563 * MEM2 = pv (present value).
565 * RESULT = log(MEM1 / MEM2) / log(1 + MEM0)
569 int MP1
[MP_SIZE
], MP2
[MP_SIZE
], MP3
[MP_SIZE
], MP4
[MP_SIZE
];
571 mpdiv(v
->MPmvals
[1], v
->MPmvals
[2], MP1
);
574 mpaddi(v
->MPmvals
[0], &val
, MP3
);
581 calc_ddb(int t
[MP_SIZE
])
584 /* Ddb - MEM0 = cost (amount paid for asset).
585 * MEM1 = salvage (value of asset at end of its life).
586 * MEM2 = life (useful life of the asset).
587 * MEM3 = period (time period for depreciation allowance).
590 * for (i = 0; i < MEM3; i++)
592 * VAL = ((MEM0 - bv) * 2) / MEM2
601 int MPbv
[MP_SIZE
], MP1
[MP_SIZE
], MP2
[MP_SIZE
];
605 mpcmi(v
->MPmvals
[3], &len
);
606 for (i
= 0; i
< len
; i
++) {
607 mpsub(v
->MPmvals
[0], MPbv
, MP1
);
609 mpmuli(MP1
, &val
, MP2
);
610 mpdiv(MP2
, v
->MPmvals
[2], t
);
612 mpadd(MP1
, t
, MPbv
); /* TODO: why result is MPbv, for next loop? */
618 calc_fv(int t
[MP_SIZE
])
621 /* Fv - MEM0 = pmt (periodic payment).
622 * MEM1 = int (periodic interest rate).
623 * MEM2 = n (number of periods).
625 * RESULT = MEM0 * (pow(1 + MEM1, MEM2) - 1) / MEM1
629 int MP1
[MP_SIZE
], MP2
[MP_SIZE
], MP3
[MP_SIZE
], MP4
[MP_SIZE
];
632 mpaddi(v
->MPmvals
[1], &val
, MP1
);
633 mppwr2(MP1
, v
->MPmvals
[2], MP2
);
635 mpaddi(MP2
, &val
, MP3
);
636 mpmul(v
->MPmvals
[0], MP3
, MP4
);
637 mpdiv(MP4
, v
->MPmvals
[1], t
);
642 calc_pmt(int t
[MP_SIZE
])
645 /* Pmt - MEM0 = prin (principal).
646 * MEM1 = int (periodic interest rate).
649 * RESULT = MEM0 * (MEM1 / (1 - pow(MEM1 + 1, -1 * MEM2)))
653 int MP1
[MP_SIZE
], MP2
[MP_SIZE
], MP3
[MP_SIZE
], MP4
[MP_SIZE
];
656 mpaddi(v
->MPmvals
[1], &val
, MP1
);
658 mpmuli(v
->MPmvals
[2], &val
, MP2
);
659 mppwr2(MP1
, MP2
, MP3
);
661 mpmuli(MP3
, &val
, MP4
);
663 mpaddi(MP4
, &val
, MP1
);
664 mpdiv(v
->MPmvals
[1], MP1
, MP2
);
665 mpmul(v
->MPmvals
[0], MP2
, t
);
670 calc_pv(int t
[MP_SIZE
])
673 /* Pv - MEM0 = pmt (periodic payment).
674 * MEM1 = int (periodic interest rate).
677 * RESULT = MEM0 * (1 - pow(1 + MEM1, -1 * MEM2)) / MEM1
681 int MP1
[MP_SIZE
], MP2
[MP_SIZE
], MP3
[MP_SIZE
], MP4
[MP_SIZE
];
684 mpaddi(v
->MPmvals
[1], &val
, MP1
);
686 mpmuli(v
->MPmvals
[2], &val
, MP2
);
687 mppwr2(MP1
, MP2
, MP3
);
689 mpmuli(MP3
, &val
, MP4
);
691 mpaddi(MP4
, &val
, MP1
);
692 mpdiv(MP1
, v
->MPmvals
[1], MP2
);
693 mpmul(v
->MPmvals
[0], MP2
, t
);
698 calc_rate(int t
[MP_SIZE
])
701 /* Rate - MEM0 = fv (future value).
702 * MEM1 = pv (present value).
705 * RESULT = pow(MEM0 / MEM1, 1 / MEM2) - 1
709 int MP1
[MP_SIZE
], MP2
[MP_SIZE
], MP3
[MP_SIZE
], MP4
[MP_SIZE
];
711 mpdiv(v
->MPmvals
[0], v
->MPmvals
[1], MP1
);
714 mpdiv(MP2
, v
->MPmvals
[2], MP3
);
715 mppwr2(MP1
, MP3
, MP4
);
717 mpaddi(MP4
, &val
, t
);
722 calc_sln(int t
[MP_SIZE
])
725 /* Sln - MEM0 = cost (cost of the asset).
726 * MEM1 = salvage (salvage value of the asset).
727 * MEM2 = life (useful life of the asset).
729 * RESULT = (MEM0 - MEM1) / MEM2
734 mpsub(v
->MPmvals
[0], v
->MPmvals
[1], MP1
);
735 mpdiv(MP1
, v
->MPmvals
[2], t
);
740 calc_syd(int t
[MP_SIZE
])
743 /* Syd - MEM0 = cost (cost of the asset).
744 * MEM1 = salvage (salvage value of the asset).
745 * MEM2 = life (useful life of the asset).
746 * MEM3 = period (period for which depreciation is computed).
748 * RESULT = ((MEM0 - MEM1) * (MEM2 - MEM3 + 1)) /
749 * (MEM2 * (MEM2 + 1) / 2)
753 int MP1
[MP_SIZE
], MP2
[MP_SIZE
], MP3
[MP_SIZE
], MP4
[MP_SIZE
];
755 mpsub(v
->MPmvals
[2], v
->MPmvals
[3], MP2
);
757 mpaddi(MP2
, &val
, MP3
);
758 mpaddi(v
->MPmvals
[2], &val
, MP2
);
759 mpmul(v
->MPmvals
[2], MP2
, MP4
);
762 mpdiv(MP4
, MP2
, MP1
);
763 mpdiv(MP3
, MP1
, MP2
);
764 mpsub(v
->MPmvals
[0], v
->MPmvals
[1], MP1
);
770 calc_term(int t
[MP_SIZE
])
773 /* Term - MEM0 = pmt (periodic payment).
774 * MEM1 = fv (future value).
775 * MEM2 = int (periodic interest rate).
777 * RESULT = log(1 + (MEM1 * MEM2 / MEM0)) / log(1 + MEM2)
781 int MP1
[MP_SIZE
], MP2
[MP_SIZE
], MP3
[MP_SIZE
], MP4
[MP_SIZE
];
784 mpaddi(v
->MPmvals
[2], &val
, MP1
);
786 mpmul(v
->MPmvals
[1], v
->MPmvals
[2], MP1
);
787 mpdiv(MP1
, v
->MPmvals
[0], MP3
);
789 mpaddi(MP3
, &val
, MP4
);
796 calc_rshift(int s
[MP_SIZE
], int t
[MP_SIZE
], int times
, enum shiftd dir
)
798 /* Implementation derived from old code.
799 * Using BOOLEAN is strange at least. Assumed that
800 * boolean means BINARY representation
808 /* There is a reason to do shift like this. Reason is that
809 * processors define shift only in a certain range. i386 uses only 5
810 * bits to describe shiftable amount. So, shift 32 times gives original
811 * number. That can cause very strange results (and bugs).
817 temp
= (dir
== right
) ? temp
>> 1 : temp
<< 1;
820 dval
= setbool(temp
);
826 is_integer(int MPnum
[MP_SIZE
])
830 return mpeq(MPnum
, MP1
);
834 is_natural(int MPnum
[MP_SIZE
])
837 if (!is_integer(MPnum
)) {
841 return mpeq(MPnum
, MP1
);
845 calc_epowy(int s
[MP_SIZE
], int t
[MP_SIZE
])