Annotation of embedaddon/php/ext/bcmath/libbcmath/src/raise.c, revision 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>