Back to index

php5  5.3.10
Functions
raise.c File Reference
#include <config.h>
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <ctype.h>
#include <stdarg.h>
#include "bcmath.h"
#include "private.h"

Go to the source code of this file.

Functions

void bc_raise (bc_num num1, bc_num num2, bc_num *result, int scale TSRMLS_DC)

Function Documentation

void bc_raise ( bc_num  num1,
bc_num  num2,
bc_num result,
int scale  TSRMLS_DC 
)

Definition at line 47 of file raise.c.

{
   bc_num temp, power;
   long exponent;
   int rscale;
   int pwrscale;
   int calcscale;
   char neg;

   /* Check the exponent for scale digits and convert to a long. */
   if (num2->n_scale != 0)
     bc_rt_warn ("non-zero scale in exponent");
   exponent = bc_num2long (num2);
   if (exponent == 0 && (num2->n_len > 1 || num2->n_value[0] != 0))
       bc_rt_error ("exponent too large in raise");

   /* Special case if exponent is a zero. */
   if (exponent == 0)
     {
       bc_free_num (result);
       *result = bc_copy_num (BCG(_one_));
       return;
     }

   /* Other initializations. */
   if (exponent < 0)
     {
       neg = TRUE;
       exponent = -exponent;
       rscale = scale;
     }
   else
     {
       neg = FALSE;
       rscale = MIN (num1->n_scale*exponent, MAX(scale, num1->n_scale));
     }

   /* Set initial value of temp.  */
   power = bc_copy_num (num1);
   pwrscale = num1->n_scale;
   while ((exponent & 1) == 0)
     {
       pwrscale = 2*pwrscale;
       bc_multiply (power, power, &power, pwrscale TSRMLS_CC);
       exponent = exponent >> 1;
     }
   temp = bc_copy_num (power);
   calcscale = pwrscale;
   exponent = exponent >> 1;

   /* Do the calculation. */
   while (exponent > 0)
     {
       pwrscale = 2*pwrscale;
       bc_multiply (power, power, &power, pwrscale TSRMLS_CC);
       if ((exponent & 1) == 1) {
        calcscale = pwrscale + calcscale;
        bc_multiply (temp, power, &temp, calcscale TSRMLS_CC);
       }
       exponent = exponent >> 1;
     }

   /* Assign the value. */
   if (neg)
     {
       bc_divide (BCG(_one_), temp, result, rscale TSRMLS_CC);
       bc_free_num (&temp);
     }
   else
     {
       bc_free_num (result);
       *result = temp;
       if ((*result)->n_scale > rscale)
        (*result)->n_scale = rscale;
     }
   bc_free_num (&power);
}

Here is the call graph for this function:

Here is the caller graph for this function: