Annotation of embedaddon/php/ext/bcmath/libbcmath/src/raise.c, revision 1.1.1.1

1.1       misho       1: /* raise.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: 
                     42: /* Raise NUM1 to the NUM2 power.  The result is placed in RESULT.
                     43:    Maximum exponent is LONG_MAX.  If a NUM2 is not an integer,
                     44:    only the integer part is used.  */
                     45: 
                     46: void
                     47: bc_raise (bc_num num1, bc_num num2, bc_num *result, int scale TSRMLS_DC)
                     48: {
                     49:    bc_num temp, power;
                     50:    long exponent;
                     51:    int rscale;
                     52:    int pwrscale;
                     53:    int calcscale;
                     54:    char neg;
                     55: 
                     56:    /* Check the exponent for scale digits and convert to a long. */
                     57:    if (num2->n_scale != 0)
                     58:      bc_rt_warn ("non-zero scale in exponent");
                     59:    exponent = bc_num2long (num2);
                     60:    if (exponent == 0 && (num2->n_len > 1 || num2->n_value[0] != 0))
                     61:        bc_rt_error ("exponent too large in raise");
                     62: 
                     63:    /* Special case if exponent is a zero. */
                     64:    if (exponent == 0)
                     65:      {
                     66:        bc_free_num (result);
                     67:        *result = bc_copy_num (BCG(_one_));
                     68:        return;
                     69:      }
                     70: 
                     71:    /* Other initializations. */
                     72:    if (exponent < 0)
                     73:      {
                     74:        neg = TRUE;
                     75:        exponent = -exponent;
                     76:        rscale = scale;
                     77:      }
                     78:    else
                     79:      {
                     80:        neg = FALSE;
                     81:        rscale = MIN (num1->n_scale*exponent, MAX(scale, num1->n_scale));
                     82:      }
                     83: 
                     84:    /* Set initial value of temp.  */
                     85:    power = bc_copy_num (num1);
                     86:    pwrscale = num1->n_scale;
                     87:    while ((exponent & 1) == 0)
                     88:      {
                     89:        pwrscale = 2*pwrscale;
                     90:        bc_multiply (power, power, &power, pwrscale TSRMLS_CC);
                     91:        exponent = exponent >> 1;
                     92:      }
                     93:    temp = bc_copy_num (power);
                     94:    calcscale = pwrscale;
                     95:    exponent = exponent >> 1;
                     96: 
                     97:    /* Do the calculation. */
                     98:    while (exponent > 0)
                     99:      {
                    100:        pwrscale = 2*pwrscale;
                    101:        bc_multiply (power, power, &power, pwrscale TSRMLS_CC);
                    102:        if ((exponent & 1) == 1) {
                    103:         calcscale = pwrscale + calcscale;
                    104:         bc_multiply (temp, power, &temp, calcscale TSRMLS_CC);
                    105:        }
                    106:        exponent = exponent >> 1;
                    107:      }
                    108: 
                    109:    /* Assign the value. */
                    110:    if (neg)
                    111:      {
                    112:        bc_divide (BCG(_one_), temp, result, rscale TSRMLS_CC);
                    113:        bc_free_num (&temp);
                    114:      }
                    115:    else
                    116:      {
                    117:        bc_free_num (result);
                    118:        *result = temp;
                    119:        if ((*result)->n_scale > rscale)
                    120:         (*result)->n_scale = rscale;
                    121:      }
                    122:    bc_free_num (&power);
                    123: }
                    124: 

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