Back to index

php5  5.3.10
Functions
private.h File Reference
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

int _bc_do_compare (bc_num n1, bc_num n2, int use_sign, int ignore_last)
bc_num _bc_do_add (bc_num n1, bc_num n2, int scale_min)
bc_num _bc_do_sub (bc_num n1, bc_num n2, int scale_min)
void _bc_rm_leading_zeros (bc_num num)

Function Documentation

bc_num _bc_do_add ( bc_num  n1,
bc_num  n2,
int  scale_min 
)

Definition at line 47 of file doaddsub.c.

{
  bc_num sum;
  int sum_scale, sum_digits;
  char *n1ptr, *n2ptr, *sumptr;
  int carry, n1bytes, n2bytes;
  int count;

  /* Prepare sum. */
  sum_scale = MAX (n1->n_scale, n2->n_scale);
  sum_digits = MAX (n1->n_len, n2->n_len) + 1;
  sum = bc_new_num (sum_digits, MAX(sum_scale, scale_min));

  /* Zero extra digits made by scale_min. */
  if (scale_min > sum_scale)
    {
      sumptr = (char *) (sum->n_value + sum_scale + sum_digits);
      for (count = scale_min - sum_scale; count > 0; count--)
       *sumptr++ = 0;
    }

  /* Start with the fraction part.  Initialize the pointers. */
  n1bytes = n1->n_scale;
  n2bytes = n2->n_scale;
  n1ptr = (char *) (n1->n_value + n1->n_len + n1bytes - 1);
  n2ptr = (char *) (n2->n_value + n2->n_len + n2bytes - 1);
  sumptr = (char *) (sum->n_value + sum_scale + sum_digits - 1);

  /* Add the fraction part.  First copy the longer fraction.*/
  if (n1bytes != n2bytes)
    {
      if (n1bytes > n2bytes)
       while (n1bytes>n2bytes)
         { *sumptr-- = *n1ptr--; n1bytes--;}
      else
       while (n2bytes>n1bytes)
         { *sumptr-- = *n2ptr--; n2bytes--;}
    }

  /* Now add the remaining fraction part and equal size integer parts. */
  n1bytes += n1->n_len;
  n2bytes += n2->n_len;
  carry = 0;
  while ((n1bytes > 0) && (n2bytes > 0))
    {
      *sumptr = *n1ptr-- + *n2ptr-- + carry;
      if (*sumptr > (BASE-1))
       {
          carry = 1;
          *sumptr -= BASE;
       }
      else
       carry = 0;
      sumptr--;
      n1bytes--;
      n2bytes--;
    }

  /* Now add carry the longer integer part. */
  if (n1bytes == 0)
    { n1bytes = n2bytes; n1ptr = n2ptr; }
  while (n1bytes-- > 0)
    {
      *sumptr = *n1ptr-- + carry;
      if (*sumptr > (BASE-1))
       {
          carry = 1;
          *sumptr -= BASE;
        }
      else
       carry = 0;
      sumptr--;
    }

  /* Set final carry. */
  if (carry == 1)
    *sumptr += 1;

  /* Adjust sum and return. */
  _bc_rm_leading_zeros (sum);
  return sum;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int _bc_do_compare ( bc_num  n1,
bc_num  n2,
int  use_sign,
int  ignore_last 
)

Definition at line 47 of file compare.c.

{
  char *n1ptr, *n2ptr;
  int  count;

  /* First, compare signs. */
  if (use_sign && n1->n_sign != n2->n_sign)
    {
      if (n1->n_sign == PLUS)
       return (1);   /* Positive N1 > Negative N2 */
      else
       return (-1);  /* Negative N1 < Positive N1 */
    }

  /* Now compare the magnitude. */
  if (n1->n_len != n2->n_len)
    {
      if (n1->n_len > n2->n_len)
       {
         /* Magnitude of n1 > n2. */
         if (!use_sign || n1->n_sign == PLUS)
           return (1);
         else
           return (-1);
       }
      else
       {
         /* Magnitude of n1 < n2. */
         if (!use_sign || n1->n_sign == PLUS)
           return (-1);
         else
           return (1);
       }
    }

  /* If we get here, they have the same number of integer digits.
     check the integer part and the equal length part of the fraction. */
  count = n1->n_len + MIN (n1->n_scale, n2->n_scale);
  n1ptr = n1->n_value;
  n2ptr = n2->n_value;

  while ((count > 0) && (*n1ptr == *n2ptr))
    {
      n1ptr++;
      n2ptr++;
      count--;
    }
  if (ignore_last && count == 1 && n1->n_scale == n2->n_scale)
    return (0);
  if (count != 0)
    {
      if (*n1ptr > *n2ptr)
       {
         /* Magnitude of n1 > n2. */
         if (!use_sign || n1->n_sign == PLUS)
           return (1);
         else
           return (-1);
       }
      else
       {
         /* Magnitude of n1 < n2. */
         if (!use_sign || n1->n_sign == PLUS)
           return (-1);
         else
           return (1);
       }
    }

  /* They are equal up to the last part of the equal part of the fraction. */
  if (n1->n_scale != n2->n_scale)
    {
      if (n1->n_scale > n2->n_scale)
       {
         for (count = n1->n_scale-n2->n_scale; count>0; count--)
           if (*n1ptr++ != 0)
             {
              /* Magnitude of n1 > n2. */
              if (!use_sign || n1->n_sign == PLUS)
                return (1);
              else
                return (-1);
             }
       }
      else
       {
         for (count = n2->n_scale-n1->n_scale; count>0; count--)
           if (*n2ptr++ != 0)
             {
              /* Magnitude of n1 < n2. */
              if (!use_sign || n1->n_sign == PLUS)
                return (-1);
              else
                return (1);
             }
       }
    }

  /* They must be equal! */
  return (0);
}

Here is the caller graph for this function:

bc_num _bc_do_sub ( bc_num  n1,
bc_num  n2,
int  scale_min 
)

Definition at line 139 of file doaddsub.c.

{
  bc_num diff;
  int diff_scale, diff_len;
  int min_scale, min_len;
  char *n1ptr, *n2ptr, *diffptr;
  int borrow, count, val;

  /* Allocate temporary storage. */
  diff_len = MAX (n1->n_len, n2->n_len);
  diff_scale = MAX (n1->n_scale, n2->n_scale);
  min_len = MIN  (n1->n_len, n2->n_len);
  min_scale = MIN (n1->n_scale, n2->n_scale);
  diff = bc_new_num (diff_len, MAX(diff_scale, scale_min));

  /* Zero extra digits made by scale_min. */
  if (scale_min > diff_scale)
    {
      diffptr = (char *) (diff->n_value + diff_len + diff_scale);
      for (count = scale_min - diff_scale; count > 0; count--)
       *diffptr++ = 0;
    }

  /* Initialize the subtract. */
  n1ptr = (char *) (n1->n_value + n1->n_len + n1->n_scale -1);
  n2ptr = (char *) (n2->n_value + n2->n_len + n2->n_scale -1);
  diffptr = (char *) (diff->n_value + diff_len + diff_scale -1);

  /* Subtract the numbers. */
  borrow = 0;

  /* Take care of the longer scaled number. */
  if (n1->n_scale != min_scale)
    {
      /* n1 has the longer scale */
      for (count = n1->n_scale - min_scale; count > 0; count--)
       *diffptr-- = *n1ptr--;
    }
  else
    {
      /* n2 has the longer scale */
      for (count = n2->n_scale - min_scale; count > 0; count--)
       {
         val = - *n2ptr-- - borrow;
         if (val < 0)
           {
             val += BASE;
             borrow = 1;
           }
         else
           borrow = 0;
         *diffptr-- = val;
       }
    }

  /* Now do the equal length scale and integer parts. */

  for (count = 0; count < min_len + min_scale; count++)
    {
      val = *n1ptr-- - *n2ptr-- - borrow;
      if (val < 0)
       {
         val += BASE;
         borrow = 1;
       }
      else
       borrow = 0;
      *diffptr-- = val;
    }

  /* If n1 has more digits then n2, we now do that subtract. */
  if (diff_len != min_len)
    {
      for (count = diff_len - min_len; count > 0; count--)
       {
         val = *n1ptr-- - borrow;
         if (val < 0)
           {
             val += BASE;
             borrow = 1;
           }
         else
           borrow = 0;
         *diffptr-- = val;
       }
    }

  /* Clean up and return. */
  _bc_rm_leading_zeros (diff);
  return diff;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 46 of file rmzero.c.

{
  /* We can move n_value to point to the first non zero digit! */
  while (*num->n_value == 0 && num->n_len > 1) {
    num->n_value++;
    num->n_len--;
  }
}

Here is the caller graph for this function: