Annotation of embedaddon/php/ext/bcmath/libbcmath/src/raisemod.c, revision 1.1

1.1     ! misho       1: /* raisemod.c: bcmath library file. */
        !             2: /*
        !             3:     Copyright (C) 1991, 1992, 1993, 1994, 1997 Free Software Foundation, Inc.
        !             4:     Copyright (C) 2000 Philip A. Nelson
        !             5: 
        !             6:     This library is free software; you can redistribute it and/or
        !             7:     modify it under the terms of the GNU Lesser General Public
        !             8:     License as published by the Free Software Foundation; either
        !             9:     version 2 of the License, or (at your option) any later version.
        !            10: 
        !            11:     This library is distributed in the hope that it will be useful,
        !            12:     but WITHOUT ANY WARRANTY; without even the implied warranty of
        !            13:     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
        !            14:     Lesser General Public License for more details.  (COPYING.LIB)
        !            15: 
        !            16:     You should have received a copy of the GNU Lesser General Public
        !            17:     License along with this library; if not, write to:
        !            18: 
        !            19:       The Free Software Foundation, Inc.
        !            20:       59 Temple Place, Suite 330
        !            21:       Boston, MA 02111-1307 USA.
        !            22: 
        !            23:     You may contact the author by:
        !            24:        e-mail:  philnelson@acm.org
        !            25:       us-mail:  Philip A. Nelson
        !            26:                 Computer Science Department, 9062
        !            27:                 Western Washington University
        !            28:                 Bellingham, WA 98226-9062
        !            29:        
        !            30: *************************************************************************/
        !            31: 
        !            32: #include <config.h>
        !            33: #include <stdio.h>
        !            34: #include <assert.h>
        !            35: #include <stdlib.h>
        !            36: #include <ctype.h>
        !            37: #include <stdarg.h>
        !            38: #include "bcmath.h"
        !            39: #include "private.h"
        !            40: 
        !            41: /* Raise BASE to the EXPO power, reduced modulo MOD.  The result is
        !            42:    placed in RESULT.  If a EXPO is not an integer,
        !            43:    only the integer part is used.  */
        !            44: 
        !            45: int
        !            46: bc_raisemod (bc_num base, bc_num expo, bc_num mod, bc_num *result, int scale TSRMLS_DC)
        !            47: {
        !            48:   bc_num power, exponent, parity, temp;
        !            49:   int rscale;
        !            50: 
        !            51:   /* Check for correct numbers. */
        !            52:   if (bc_is_zero(mod TSRMLS_CC)) return -1;
        !            53:   if (bc_is_neg(expo)) return -1;
        !            54: 
        !            55:   /* Set initial values.  */
        !            56:   power = bc_copy_num (base);
        !            57:   exponent = bc_copy_num (expo);
        !            58:   temp = bc_copy_num (BCG(_one_));
        !            59:   bc_init_num(&parity TSRMLS_CC);
        !            60: 
        !            61:   /* Check the base for scale digits. */
        !            62:   if (base->n_scale != 0)
        !            63:       bc_rt_warn ("non-zero scale in base");
        !            64: 
        !            65:   /* Check the exponent for scale digits. */
        !            66:   if (exponent->n_scale != 0)
        !            67:     {
        !            68:       bc_rt_warn ("non-zero scale in exponent");
        !            69:       bc_divide (exponent, BCG(_one_), &exponent, 0 TSRMLS_CC); /*truncate */
        !            70:     }
        !            71: 
        !            72:   /* Check the modulus for scale digits. */
        !            73:   if (mod->n_scale != 0)
        !            74:       bc_rt_warn ("non-zero scale in modulus");
        !            75: 
        !            76:   /* Do the calculation. */
        !            77:   rscale = MAX(scale, base->n_scale);
        !            78:   while ( !bc_is_zero(exponent TSRMLS_CC) )
        !            79:     {
        !            80:       (void) bc_divmod (exponent, BCG(_two_), &exponent, &parity, 0 TSRMLS_CC);
        !            81:       if ( !bc_is_zero(parity TSRMLS_CC) )
        !            82:        {
        !            83:          bc_multiply (temp, power, &temp, rscale TSRMLS_CC);
        !            84:          (void) bc_modulo (temp, mod, &temp, scale TSRMLS_CC);
        !            85:        }
        !            86: 
        !            87:       bc_multiply (power, power, &power, rscale TSRMLS_CC);
        !            88:       (void) bc_modulo (power, mod, &power, scale TSRMLS_CC);
        !            89:     }
        !            90: 
        !            91:   /* Assign the value. */
        !            92:   bc_free_num (&power);
        !            93:   bc_free_num (&exponent);
        !            94:   bc_free_num (result);
        !            95:   bc_free_num (&parity);
        !            96:   *result = temp;
        !            97:   return 0;    /* Everything is OK. */
        !            98: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>