/***********************************************************************************
 * Chaga string arithmetic library                                                 *
 * Copyright (C) 2026 Robert James Bruce                                           *
 *                                                                                 *
 * This file is part of the Chaga string arithmetic library.                       *
 *                                                                                 *
 * The Chaga string arithmetic library is free software: you can redistribute it   * 
 * and/or modify it under the terms of the GNU General Public License as published *
 * by the Free Software Foundation, either version 3 of the License, or (at your   *
 * option) any later version.                                                      *
 *                                                                                 *
 * The Chaga string arithmetic library is distributed in the hope that it will be  *
 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of          *
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public *
 * License for more details.                                                       *
 *                                                                                 *
 * You should have received a copy of the GNU General Public License               *
 * along with the Chaga compiler. If not, see <https://www.gnu.org/licenses/>.     *
 ***********************************************************************************/
#include "include/libchaga-packed_string_integer_functions.h"
#include "include/libchaga-diagnostic_tools.h"
#include "include/libchaga-general_functions.h"

// ****************************************************************************************
// * packed_string_integer_release_memory                                                 *
// *                                                                                      *
// * This function releases memory formerly allocated for a packed, string-based integer. *
// *                                                                                      *
// * Input:  pointer to a string number                                                   *
// * Output: NULL                                                                         *
// ****************************************************************************************
psint * packed_string_integer_release_memory (psint *number)
{
  psnc *temp_number_component, *number_component;
  
  if (number != NULL)
  {
    number_component = number->left_of_decimal;
    while (number_component != NULL)
    {
      temp_number_component = number_component;
      number_component = number_component->next_number_block;
      free (temp_number_component);
      temp_number_component = NULL;
    }
    free (number);
    number = NULL;
  }
  return number;
}




psint * packed_string_integer_component_release_memory (psint *number)
{
  psnc *temp_number_component, *number_component;
  
  if (number != NULL)
  {
    number_component = number->left_of_decimal;
    while (number_component != NULL)
    {
      temp_number_component = number_component;
      number_component = number_component->next_number_block;
      free (temp_number_component);
      temp_number_component = NULL;
    }
    number->left_of_decimal = NULL;
  }
  return number;
}




// **************************************************************************
// * packed_string_integer_copy_number                                      *
// *                                                                        *
// * This function makes a duplicate copy of a stringint data structure.    *
// *                                                                        *
// * Input:  The string-based integer number to copy.                       *
// * Output: NULL on failure; pointer to a string-based integer on success. *
// **************************************************************************
psint * packed_string_integer_copy_number (psint *number_copy_head, psint *number)
{
  psnc *new_number_block, *number_copy_previous, *temp_num;
  int state;
  unsigned char nibble_lo, packed_byte;
  long long int i;

// *************************************************************************
// * Release any previously used memory otherwise we'd have a memory leak. *
// *************************************************************************
  if (number_copy_head != NULL)
  {
    number_copy_head = packed_string_integer_component_release_memory (number_copy_head);
  }
  if (number != NULL)
  {
    if (number_copy_head == NULL)
    {
      number_copy_head = (psint *) malloc(sizeof(psint));
    }
    if (number_copy_head != NULL)
    {
      number_copy_head->sign            = number->sign;
      number_copy_head->status_flag     = number->status_flag;
      number_copy_head->left_of_decimal = NULL;
      number_copy_head->scale           = number->scale;
      if (number->left_of_decimal != NULL)
      {
        new_number_block     = NULL;
        number_copy_previous = NULL;
        nibble_lo            = 0;
        packed_byte          = 0;
        state                = 0;
        temp_num             = number->left_of_decimal;
        while (temp_num != NULL)
        {
          new_number_block = (psnc *) malloc(sizeof(psnc));
          if (new_number_block != NULL)
          {
            new_number_block->highest_digit_position  = temp_num->highest_digit_position;
            new_number_block->highest_nibble_position = temp_num->highest_nibble_position;
            new_number_block->first_number_block      = NULL;
            new_number_block->last_number_block       = NULL;
            new_number_block->previous_number_block   = NULL;
            new_number_block->next_number_block       = NULL;
            for (i = temp_num->highest_digit_position + 1; i < MAX_PACKED_NUMBER_BLOCK_SIZE; i++)
            {
              new_number_block->packed_number_block[i] = 0;
            }
            for (i = 0; i < temp_num->highest_digit_position; i++)
            {
              new_number_block->packed_number_block[i] = temp_num->packed_number_block[i];
            }
            if (temp_num->highest_nibble_position == hi)
            {
              new_number_block->packed_number_block[i] = temp_num->packed_number_block[i];
            }
            else
            {
              if (temp_num->highest_nibble_position == lo)
              {
                packed_byte = temp_num->packed_number_block[i];
                nibble_lo = packed_byte & 0x0f;
                new_number_block->packed_number_block[i] = nibble_lo;
              }
            }
            switch (state)
            {
              case 0:
                number_copy_head->left_of_decimal = new_number_block;
                number_copy_head->left_of_decimal->first_number_block = new_number_block;
                number_copy_previous = NULL;
                state  = 10;
              break;
              case 10:
                if (number_copy_previous != NULL)
                {
                  number_copy_previous->next_number_block = new_number_block;
                }
                new_number_block->first_number_block    = number_copy_head->left_of_decimal;
                new_number_block->previous_number_block = number_copy_previous; 
              break;
              default:
              break;
            }
            number_copy_previous = new_number_block;
          }
          temp_num = temp_num->next_number_block;
        }
        if (new_number_block != NULL)
        {
          temp_num = number_copy_head->left_of_decimal;
          while (temp_num != NULL)
          {
            temp_num->last_number_block = new_number_block;
            temp_num = temp_num->next_number_block;
          }
        }
      }
    }
  }
  return number_copy_head;
} 




// **********************************************************************************************************************
// * packed_string_integer_set_sign                                                                                     *
// *                                                                                                                    *
// * This subroutine adds the sign to an existing number. If no number exists, it will allocate memory to store a sign. *         
// **********************************************************************************************************************
psint * packed_string_integer_set_sign (psint *number, enum string_number_sign sign)
{
  if (number != NULL)
  {
    number->sign = sign;
    if (number->sign == zero)
    {
      if (number->left_of_decimal != NULL)
      {
        number = packed_string_integer_component_release_memory (number);
      }
    }
  }
  else
  {
    number = (psint *) malloc(sizeof(psint));
    if (number != NULL)
    {
      number->sign = sign;
      number->status_flag = 0;
      number->left_of_decimal = NULL;
    }
  }
  return number;
}




// ***************************************************************************************************************
// * packed_string_integer_set_status                                                                            *
// *                                                                                                             *
// * This subroutine updates the status bits for certain math operations such as division (e.g. divide by zero). * 
// ***************************************************************************************************************
psint * packed_string_integer_set_status_flag (psint *number, unsigned int status_flag)
{
  switch (status_flag)
  {
    case NONE:
    case INTERNAL_ERROR:
    case DIVIDE_BY_ZERO:
    case REPEATING_NONTERMINATING:
    case IMAGINARY:
      if (number != NULL)
      { 
        number->status_flag = status_flag;
      }
      else
      {
        number = (psint *) malloc(sizeof(psint));
        if (number != NULL)
        {
          number->sign = zero;
          number->status_flag = status_flag;
          number->left_of_decimal = NULL;
        }
      }
    break;
    default:
      printf ("ERROR in packed_string_integer_set_status_flag(): invalid status flag encountered. Exiting now.\n");
      exit (EXIT_FAILURE);
    break;
  }
  return number;
}




psint * packed_string_integer_initialize_to_zero (psint *number)
{
// *************************************************************************
// * Release any previously used memory otherwise we'd have a memory leak. *
// *************************************************************************
  if (number != NULL)
  {
    number = packed_string_integer_component_release_memory (number); // release the LEFT of DECIMAL number component (if exists) since initializing to zero requires LEFT of DECIMAL number component to be NULL;
  }
  else
  {
    number = (psint *) malloc(sizeof(psint));
  }
  if (number != NULL)
  {
    number->sign = zero;
    number->status_flag = 0;
    number->left_of_decimal = NULL;
  }
  return number;
}




psint * packed_string_integer_initialize_to_undefined (psint *number)
{
// *************************************************************************
// * Release any previously used memory otherwise we'd have a memory leak. *
// *************************************************************************
  if (number != NULL)
  {
    number = packed_string_integer_component_release_memory (number); // release the LEFT of DECIMAL number component (if exists) since initializing to zero requires LEFT of DECIMAL number component to be NULL;
  }
  else
  {
    number = (psint *) malloc(sizeof(psint));
  }
  if (number != NULL)
  {
    number->sign = undefined;
    number->status_flag = 0;
    number->left_of_decimal = NULL;
  }
  return number;
}




// ****************************************************************************************************************************************
// * packed_string_integer_append_one_digit                                                                                               *
// *                                                                                                                                      *
// * This subroutine manages string-based integers. It appends ONE new digit after the current highest position digit in the string-based *
// * integer. If a digit is added to a number beyond the string block size (defined by MAX_PACKED_NUMBER_BLOCK_SIZE) then a new string    * 
// * block is allocated to append the new digit.                                                                                          *
// ****************************************************************************************************************************************
psint * packed_string_integer_append_one_digit (psint *number, unsigned char new_packed_digit)
{
  psnc *temp_number_block, *new_number_block, *number_block;
  psnc *string_integer_component;
  unsigned char packed_digits, nibble_low, nibble_high;
  long long int i;

  temp_number_block        = NULL;
  new_number_block         = NULL;
  string_integer_component = NULL;
  if (number != NULL)
  { 
    if (number->left_of_decimal != NULL)
    {
      number_block = number->left_of_decimal;
      if (number_block->last_number_block != NULL)
      {
        number_block = number_block->last_number_block;
        if ((number_block->highest_digit_position >= 0) && (number_block->highest_digit_position < MAX_PACKED_NUMBER_BLOCK_SIZE - 1)) // Note: each byte holds two digits
        {
// *********************************************************
// * There is available space in the current number block. *
// *********************************************************
          if (number_block->highest_nibble_position == lo)
          {
            i = number_block->highest_digit_position;
            nibble_low  = number_block->packed_number_block[i] & 0x0f;
            nibble_high = new_packed_digit & 0x0f;
            packed_digits = (nibble_high << 4) + nibble_low;
            number_block->packed_number_block[i] = packed_digits;
            number_block->highest_nibble_position = hi;
          }
          else
          {
            number_block->highest_digit_position = number_block->highest_digit_position + 1;
            i = number_block->highest_digit_position;
            nibble_low = new_packed_digit & 0x0f;
            number_block->packed_number_block[i] = nibble_low;
            number_block->highest_nibble_position = lo;
          }
        }
        else
        {
          if ((number_block->highest_digit_position == MAX_PACKED_NUMBER_BLOCK_SIZE - 1) && (number_block->highest_nibble_position == lo))
          {
            i = number_block->highest_digit_position;
            nibble_low  = number_block->packed_number_block[i] & 0x0f;
            nibble_high = new_packed_digit & 0x0f;
            packed_digits = (nibble_high << 4) + nibble_low;
            number_block->packed_number_block[i] = packed_digits;
            number_block->highest_nibble_position = hi;
          }
          else
          {           
// ****************************************************************************************************************************************
// * The current number block is full. Hence, must allocate a new number block and append the new packed pair of digits to the new block. *
// * Then link the new number block into existing number blocks.                                                                          *
// ****************************************************************************************************************************************
            new_number_block = (psnc *) malloc(sizeof(psnc));
            if (new_number_block != NULL)
            {
              for (i = 1; i < MAX_PACKED_NUMBER_BLOCK_SIZE; i++)
              {
                new_number_block->packed_number_block[i] = 0;
              }
              nibble_low = new_packed_digit & 0x0f;
              new_number_block->packed_number_block[0]  = nibble_low;
              new_number_block->highest_digit_position  = 0;
              new_number_block->highest_nibble_position = lo;
              new_number_block->first_number_block      = number->left_of_decimal;
              new_number_block->last_number_block       = new_number_block;
              new_number_block->previous_number_block   = number_block; // number_block points to the former last number block
              new_number_block->next_number_block       = NULL;
              number_block->next_number_block = new_number_block;
// *************************************************************************
// * Now update all existing number blocks with the NEW last number block. *
// *************************************************************************
              temp_number_block = number->left_of_decimal;
              while (temp_number_block != NULL)
              {
                temp_number_block->last_number_block = new_number_block;
                temp_number_block = temp_number_block->next_number_block;
              }
            }
            else
            {
              printf ("ERROR: malloc failed to allocate memory for new number block.\n");
              exit (1);
            }
          }
        }
      }
      else
      {
        printf ("ERROR: last_number_block is NULL in packed_string_integer_append_two_digits subroutine.\n");
        exit (1);
      }
    }
    else
    {
      string_integer_component = (psnc *) malloc(sizeof(psnc));
      if (string_integer_component != NULL)
      {
        for (i = 1; i < MAX_PACKED_NUMBER_BLOCK_SIZE; i++)
        {
          string_integer_component->packed_number_block[i] = 0;
        }
        nibble_low = new_packed_digit & 0x0f;
        string_integer_component->packed_number_block[0]  = nibble_low;
        string_integer_component->highest_digit_position  = 0;
        string_integer_component->highest_nibble_position = lo;
        string_integer_component->first_number_block      = string_integer_component;
        string_integer_component->last_number_block       = string_integer_component;
        string_integer_component->previous_number_block   = NULL;
        string_integer_component->next_number_block       = NULL;
        number->left_of_decimal = string_integer_component;
      }
    }
  }
  else
  {
    number = (psint *) malloc(sizeof(psint));
    if (number != NULL)
    {
      number->sign            = positive;
      number->status_flag     = NONE;
      number->left_of_decimal = NULL;
      string_integer_component = (psnc *) malloc(sizeof(psnc));
      if (string_integer_component != NULL)
      {
        number->left_of_decimal = string_integer_component;
        for (i = 1; i < MAX_PACKED_NUMBER_BLOCK_SIZE; i++)
        {
          string_integer_component->packed_number_block[i] = 0;
        }
        nibble_low = new_packed_digit & 0x0f;
        string_integer_component->packed_number_block[0]  = nibble_low;
        string_integer_component->highest_digit_position  = 0;
        string_integer_component->highest_nibble_position = lo;
        string_integer_component->first_number_block      = string_integer_component;
        string_integer_component->last_number_block       = string_integer_component;
        string_integer_component->previous_number_block   = NULL;
        string_integer_component->next_number_block       = NULL;
        number->left_of_decimal = string_integer_component;
      }
    }
    else
    {
      printf ("ERROR: malloc() failed to allocate memory in function string_append_digits. Exiting now.\n");
      exit (1);
    }
  }
  return number;
}




// *****************************************************************************************************************************************
// * packed_string_integer_append_two_digits                                                                                               *
// *                                                                                                                                       *
// * This subroutine manages string-based integers. It appends TWO new digits after the current highest position digit in the string-based *
// * integer. If a digit is added to a number beyond the string block size (defined by MAX_PACKED_NUMBER_BLOCK_SIZE) then a new string     * 
// * block is allocated to append the new digit.                                                                                           *
// *****************************************************************************************************************************************
psint * packed_string_integer_append_two_digits (psint *number, unsigned char new_packed_digits)
{
  psnc *temp_number_block, *new_number_block, *number_block;
  psnc *string_integer_component;
  unsigned char packed_digits, nibble_low, nibble_high;
  long long int i;

  temp_number_block        = NULL;
  new_number_block         = NULL;
  string_integer_component = NULL;
  if (number != NULL)
  { 
    if (number->left_of_decimal != NULL)
    {
      number_block = number->left_of_decimal;
      if (number_block->last_number_block != NULL)
      {
        number_block = number_block->last_number_block;
        if ((number_block->highest_digit_position >= 0) && (number_block->highest_digit_position < MAX_PACKED_NUMBER_BLOCK_SIZE)) // Note: each byte holds two digits
        {
// ****************************************************************************
// * There is available space in the current number block for two new digits. *
// ****************************************************************************
          if (number_block->highest_nibble_position == lo) // do I have to split the new_packed_digits then repack into existing number block high nibble?
          {
            i = number_block->highest_digit_position;
            nibble_low  = number_block->packed_number_block[i] & 0x0f;
            nibble_high = new_packed_digits & 0x0f;
            packed_digits = (nibble_high << 4) + nibble_low;
            number_block->packed_number_block[i] = packed_digits;
            number_block->highest_nibble_position = hi;
            if ((i+1) < MAX_PACKED_NUMBER_BLOCK_SIZE)
            {
              number_block->highest_digit_position = number_block->highest_digit_position + 1;
              i = number_block->highest_digit_position;
              nibble_low = (new_packed_digits & 0xf0) >> 4;
              number_block->packed_number_block[i] = nibble_low;
              number_block->highest_nibble_position = lo;
            }
            else
            {
// ***********************************************************************************************************************
// * The current number block is full. Hence, must allocate a new number block and append one nibble into the new block. *
// * Then link the new number block into existing number blocks.                                                         *
// ***********************************************************************************************************************
              nibble_low = (new_packed_digits & 0xf0) >> 4;
              new_number_block = (psnc *) malloc(sizeof(psnc));
              if (new_number_block != NULL)
              {
                for (i = 1; i < MAX_PACKED_NUMBER_BLOCK_SIZE; i++)
                {
                  new_number_block->packed_number_block[i] = 0;
                }
                new_number_block->packed_number_block[0]  = nibble_low;
                new_number_block->highest_digit_position  = 0;
                new_number_block->highest_nibble_position = lo;
                new_number_block->first_number_block      = number->left_of_decimal;
                new_number_block->last_number_block       = new_number_block;
                new_number_block->previous_number_block   = number_block; // number_block points to the former last number block
                new_number_block->next_number_block       = NULL;
                number_block->next_number_block = new_number_block;
// *************************************************************************
// * Now update all existing number blocks with the NEW last number block. *
// *************************************************************************
                temp_number_block = number->left_of_decimal;
                while (temp_number_block != NULL)
                {
                  temp_number_block->last_number_block = new_number_block;
                  temp_number_block = temp_number_block->next_number_block;
                }
              }
              else
              {
                printf ("ERROR: malloc failed to allocate memory for new number block.\n");
                exit (1);
              }
            }
          }
          else
          {
            if ((number_block->highest_digit_position + 1) < MAX_PACKED_NUMBER_BLOCK_SIZE)
            {
              number_block->highest_digit_position++;
              i = number_block->highest_digit_position;
              number_block->packed_number_block[i] = new_packed_digits;
              number_block->highest_nibble_position = hi;
            }
            else
            {
// ****************************************************************************************************************************************
// * The current number block is full. Hence, must allocate a new number block and append the new packed pair of digits to the new block. *
// * Then link the new number block into existing number blocks.                                                                          *
// ****************************************************************************************************************************************
              new_number_block = (psnc *) malloc(sizeof(psnc));
              if (new_number_block != NULL)
              {
                for (i = 1; i < MAX_PACKED_NUMBER_BLOCK_SIZE; i++)
                {
                  new_number_block->packed_number_block[i] = 0;
                }
                new_number_block->packed_number_block[0]  = new_packed_digits;
                new_number_block->highest_digit_position  = 0;
                new_number_block->highest_nibble_position = hi;
                new_number_block->first_number_block      = number->left_of_decimal;
                new_number_block->last_number_block       = new_number_block;
                new_number_block->previous_number_block   = number_block; // number_block points to the former last number block
                new_number_block->next_number_block       = NULL;
                number_block->next_number_block = new_number_block;
// *************************************************************************
// * Now update all existing number blocks with the NEW last number block. *
// *************************************************************************
                temp_number_block = number->left_of_decimal;
                while (temp_number_block != NULL)
                {
                  temp_number_block->last_number_block = new_number_block;
                  temp_number_block = temp_number_block->next_number_block;
                }
              }
              else
              {
                printf ("ERROR: malloc failed to allocate memory for new number block.\n");
                exit (1);
              }
            }
          }
        }
        else
        {
// ****************************************************************************************************************************************
// * The current number block is full. Hence, must allocate a new number block and append the new packed pair of digits to the new block. *
// * Then link the new number block into existing number blocks.                                                                          *
// ****************************************************************************************************************************************
          new_number_block = (psnc *) malloc(sizeof(psnc));
          if (new_number_block != NULL)
          {
            for (i = 1; i < MAX_PACKED_NUMBER_BLOCK_SIZE; i++)
            {
              new_number_block->packed_number_block[i] = 0;
            }
            new_number_block->packed_number_block[0]  = new_packed_digits;
            new_number_block->highest_digit_position  = 0;
            new_number_block->highest_nibble_position = hi;
            new_number_block->first_number_block      = number->left_of_decimal;
            new_number_block->last_number_block       = new_number_block;
            new_number_block->previous_number_block   = number_block; // number_block points to the former last number block
            new_number_block->next_number_block       = NULL;
            number_block->next_number_block = new_number_block;
// *************************************************************************
// * Now update all existing number blocks with the NEW last number block. *
// *************************************************************************
            temp_number_block = number->left_of_decimal;
            while (temp_number_block != NULL)
            {
              temp_number_block->last_number_block = new_number_block;
              temp_number_block = temp_number_block->next_number_block;
            }
          }
          else
          {
            printf ("ERROR: malloc failed to allocate memory for new number block.\n");
            exit (1);
          }
        }
      }
      else
      {
        printf ("ERROR: last_number_block is NULL in packed_string_integer_append_two_digits subroutine.\n");
        exit (1);
      }
    }
    else
    {
      string_integer_component = (psnc *) malloc(sizeof(psnc));
      if (string_integer_component != NULL)
      {
        number->left_of_decimal = string_integer_component;
        string_integer_component->packed_number_block[0] = new_packed_digits;
        for (i = 1; i < MAX_PACKED_NUMBER_BLOCK_SIZE; i++)
        {
          string_integer_component->packed_number_block[i] = 0;
        }
        string_integer_component->highest_digit_position  = 0;
        string_integer_component->highest_nibble_position = hi;
        string_integer_component->first_number_block      = string_integer_component;
        string_integer_component->last_number_block       = string_integer_component;
        string_integer_component->previous_number_block   = NULL;
        string_integer_component->next_number_block       = NULL;
      }
    }
  }
  else
  {
    number = (psint *) malloc(sizeof(psint));
    if (number != NULL)
    {
      number->sign            = positive;
      number->status_flag     = NONE;
      number->left_of_decimal = NULL;
      string_integer_component = (psnc *) malloc(sizeof(psnc));
      if (string_integer_component != NULL)
      {
        number->left_of_decimal = string_integer_component;
        string_integer_component->packed_number_block[0] = new_packed_digits;
        for (i = 1; i < MAX_PACKED_NUMBER_BLOCK_SIZE; i++)
        {
          string_integer_component->packed_number_block[i] = 0;
        }
        string_integer_component->highest_digit_position  = 0;
        string_integer_component->highest_nibble_position = hi;
        string_integer_component->first_number_block      = string_integer_component;
        string_integer_component->last_number_block       = string_integer_component;
        string_integer_component->previous_number_block   = NULL;
        string_integer_component->next_number_block       = NULL;
      }
    }
    else
    {
      printf ("ERROR: malloc() failed to allocate memory in function string_append_digits. Exiting now.\n");
      exit (EXIT_FAILURE);
    }
  }
  return number;
}




// *************************************************************************************************************
// * packed_string_integer_set_value                                                                           *
// *                                                                                                           *
// * This function loads an unsigned NULL-terminated character string (representing an integer) into a packed, *
// * string-based integer                                                                                      *
// *                                                                                                           *
// * Note: the input may use the following ASCII symbols: {0,1,2,3,4,5,6,7,8,9,+,-}                            *
// *************************************************************************************************************
psint * packed_string_integer_set_value (psint *number, char *string_value)
{
  unsigned char byte, number_is_negative;
  unsigned char left_of_decimal_nonzero_digit_found;
  int state;
  size_t i, string_value_length;
  digit_stack_node *temp_digit_stack;

  left_of_decimal_nonzero_digit_found = FALSE;
  number_is_negative = FALSE;
  temp_digit_stack = NULL;
//
// *************************************************************************
// * Release any previously used memory otherwise we'd have a memory leak. *
// *************************************************************************
  if (number != NULL)
  {
    number = packed_string_integer_component_release_memory (number); // release the LEFT of DECIMAL number component (if exists) since initializing to zero requires LEFT of DECIMAL number component to be NULL;
  }
  if (string_value != NULL)
  {
// ********************************************************************************
// * Preprocess the input string to check for leading zeroes (LEFT of DECIMAL).   *
// *                                                                              *
// * Example:                                                                     *
// *                                                                              *
// * Leading zeros LEFT of DECIMAL: 000012345                                     *
// *                                                                              *
// * Leading zeroes must be removed from the input string otherwise these leading *
// * zeroes will be added to the packed string integer.                           *
// * ******************************************************************************
    string_value_length = strnlen (string_value, 4096);
    state = 0;
    i = 0;
    while ((i < string_value_length) && (state < 999))
    {
      byte = string_value[i];
      //printf ("i = %ld, byte = %c, state = %d\n", i, byte, state);
      switch (state)
      {
        case 0:
          if (byte == '0')
          {
            state = 10;
          }
          else
          {
            if ((byte >= '1') && (byte <= '9'))
            {
              left_of_decimal_nonzero_digit_found = TRUE;
              temp_digit_stack = push_digit_stack (temp_digit_stack, byte);
              state = 30;
            }
            else
            {
              if (byte == '+')
              {
                number_is_negative = FALSE;
                state = 20;
              }
              else
              {
                if (byte== '-')
                {
                  number_is_negative = TRUE;
                  state = 20;
                }
                else
                {
                  state = 999;
                }
              }
            }
          }
        break;
        case 10:
          if ((byte >= '1') && (byte <= '9'))
          {
            left_of_decimal_nonzero_digit_found = TRUE;
            temp_digit_stack = push_digit_stack (temp_digit_stack, byte);
            state = 30;
          }
          else
          {
            if (byte == '0')
            {
              state = 10;
            }
            else
            {
              state = 999;
            }
          }
        break;
        case 20:
          if ((byte >= '1') && (byte <= '9'))
          {
            left_of_decimal_nonzero_digit_found = TRUE;
            temp_digit_stack = push_digit_stack (temp_digit_stack, byte);
            state = 30;
          }
          else
          {
            if (byte == '0')
            {
              state = 20;
            }
            else
            {
              state = 999;
            }
          }
        break;
        case 30:
          if ((byte >= '0') && (byte <= '9'))
          {
            temp_digit_stack = push_digit_stack (temp_digit_stack, byte);
          }
          else
          {
            state = 999;
          }
        break;
        default:
        break;
      }
      i++;
    }
    if (state == 999)
    {
      while (temp_digit_stack != NULL)
      {
        temp_digit_stack = pop_digit_stack (temp_digit_stack);
      }  
    }
    else
    {
      if (!left_of_decimal_nonzero_digit_found)
      {
        number = packed_string_integer_initialize_to_zero (number);
        while (temp_digit_stack != NULL)
        {
          temp_digit_stack = pop_digit_stack (temp_digit_stack);
        }
      }
      else
      {
        while (temp_digit_stack != NULL)
        {
          byte = top_digit_stack (temp_digit_stack);
          byte = byte - '0';
          number = packed_string_integer_append_one_digit (number, byte);
          temp_digit_stack = pop_digit_stack (temp_digit_stack);
        }
        if (number_is_negative)
        {
          number = packed_string_integer_set_sign (number, negative);
        }
        else
        {
          number = packed_string_integer_set_sign (number, positive);
        }  
        number = packed_string_integer_set_status_flag (number, NONE);
      }
    }
  }
// *************************************************************
// * Free up memory from temporary stack (if it still exists). *
// *************************************************************
  while (temp_digit_stack != NULL)
  {
    temp_digit_stack = pop_digit_stack (temp_digit_stack);
  }
  return number;
}




// ****************************************************************************************************************************************************
// * packed_string_integer_append_unpacked_digit_string                                                                                               *
// *                                                                                                                                                  *
// * This subroutine appends a string of UNPACKED ASCII digits "0" through "9" before the highest digit position of the packed, string-based integer. *
// *                                                                                                                                                  *
// * Example:                                                                                                                                         *
// * Current number:             55555                                                                                                                *
// * String of digits to append: 98765432109876543210987654321021                                                                                     *
// * Result:                     9876543210987654321098765432102155555                                                                                *
// *                                                                                                                                                  *
// * INPUTS:                                                                                                                                          *
// * packed string-based integer                                                                                                                      *
// * string of digits: pointer to an unsigned character string containing ASCII digits "0" through "9" followed by a NULL.                            *
// * NOTE: The maximum number of bytes to append is 1024 bytes                                                                                        *
// *                                                                                                                                                  *
// * OUTPUT:                                                                                                                                          *
// * packed string-based integer                                                                                                                      *
// ****************************************************************************************************************************************************
psint * packed_string_integer_append_unpacked_digit_string (psint *number, char *new_unpacked_ascii_digits_to_append)
{
  unsigned char new_digit;
  int j, string_length_new_unpacked_ascii_digits_to_append;

  if (new_unpacked_ascii_digits_to_append != NULL)
  {
    string_length_new_unpacked_ascii_digits_to_append = strnlen (new_unpacked_ascii_digits_to_append, 1024);
    if (string_length_new_unpacked_ascii_digits_to_append > 0)
    {
      j = string_length_new_unpacked_ascii_digits_to_append - 1;
      while (j >= 0)
      {
        new_digit = new_unpacked_ascii_digits_to_append[j];
        if ((new_digit >= '0') && (new_digit <= '9'))
        {
          number = packed_string_integer_append_one_digit (number, new_digit);
        }
        j--;
      }
    }
  }
  return number;
}




psint * _packed_string_integer_add_both_numbers_same_sign (psint *sum, psint *num1, psint *num2)
{
  psnc *temp_num1_integer_component, *temp_num2_integer_component;
  unsigned char carry, num1_packed_byte, num2_packed_byte, num1_nibble_low, num2_nibble_low, num1_nibble_high, num2_nibble_high, sum_nibble_low, sum_nibble_high, sum_packed_byte;
  long long int i, num1_highest_digit_position, num2_highest_digit_position, highest_digit_position;
  enum occupied_nibble highest_nibble_position;

// *************************************************************************
// * Release any previously used memory otherwise we'd have a memory leak. *
// *************************************************************************
  if (sum != NULL)
  {
    sum = packed_string_integer_component_release_memory (sum); // release the LEFT of DECIMAL number component (if exists) since initializing to zero requires LEFT of DECIMAL number component to be NULL;
  }
  carry = 0;
  if ((num1 != NULL) && (num2 != NULL))
  {
    if ((num1->left_of_decimal != NULL) && (num2->left_of_decimal != NULL))
    {
      temp_num1_integer_component = num1->left_of_decimal;
      temp_num2_integer_component = num2->left_of_decimal;
      while ((temp_num1_integer_component != NULL) && (temp_num2_integer_component != NULL)) 
      {
        num1_highest_digit_position = temp_num1_integer_component->highest_digit_position;
        num2_highest_digit_position = temp_num2_integer_component->highest_digit_position;
        if ((num1_highest_digit_position >= 0) && (num1_highest_digit_position < MAX_PACKED_NUMBER_BLOCK_SIZE) &&
            (num2_highest_digit_position >= 0) && (num2_highest_digit_position < MAX_PACKED_NUMBER_BLOCK_SIZE))
        {
          if (num1_highest_digit_position < num2_highest_digit_position)
          {
            highest_digit_position = temp_num1_integer_component->highest_digit_position;
            highest_nibble_position = temp_num1_integer_component->highest_nibble_position;
          }
          else
          {
            if (num1_highest_digit_position > num2_highest_digit_position)
            {
              highest_digit_position = temp_num2_integer_component->highest_digit_position;
              highest_nibble_position = temp_num2_integer_component->highest_nibble_position;
            }
            else
            {
              if (num1_highest_digit_position == num2_highest_digit_position)
              {
                highest_digit_position = num1_highest_digit_position;
                if ((temp_num1_integer_component->highest_nibble_position == hi) && (temp_num2_integer_component->highest_nibble_position == hi))
                {
                  highest_nibble_position = hi;
                }
                else
                {
                  if ((temp_num1_integer_component->highest_nibble_position == hi) && (temp_num2_integer_component->highest_nibble_position == lo))
                  {
                    highest_nibble_position = lo;
                  }
                  else
                  {
                    if ((temp_num1_integer_component->highest_nibble_position == lo) && (temp_num2_integer_component->highest_nibble_position == hi))
                    {
                      highest_nibble_position = lo;
                    }
                    else
                    {
                      if ((temp_num1_integer_component->highest_nibble_position == lo) && (temp_num2_integer_component->highest_nibble_position == lo))
                      {
                        highest_nibble_position = lo;
                      }
                      else
                      {
                        printf ("Error in _packed_string_integer_add_both_numbers_same_sign(): failed to determine highest digit nibble position for num1 and num2. Exiting now.\n");
                        exit (EXIT_FAILURE);
                      }
                    }
                  }
                }
              }
              else
              {
                printf ("Error in _packed_string_integer_add_both_numbers_same_sign(): failed to determine highest digit position for num1 and num2. Exiting now.\n");
                exit (EXIT_FAILURE);
              }
            }
          }
          for (i = 0; i < highest_digit_position; i++)
          {
            num1_nibble_high = 0;
            num2_nibble_high = 0;
            num1_nibble_low  = 0;
            num2_nibble_low  = 0;
// *************************************************************************
// * Two Binary Coded Decimal (BCD) 4-bit digits are packed in each byte.  *
// * Unpack the bytes into lower and upper nibbles.                        *
// *************************************************************************
            //printf ("i = %llu, num1->highest_digit_position = %lld\n", i, temp_num1_integer_component->highest_digit_position);
            //printf ("i = %llu, num2->highest_digit_position = %lld\n", i, temp_num2_integer_component->highest_digit_position);
            num1_packed_byte = temp_num1_integer_component->packed_number_block[i];
            num2_packed_byte = temp_num2_integer_component->packed_number_block[i];
            num1_nibble_low  = num1_packed_byte & 0x0f;
            num1_nibble_high = (num1_packed_byte & 0xf0) >> 4;
            num2_nibble_low  = num2_packed_byte & 0x0f;
            num2_nibble_high = (num2_packed_byte & 0xf0) >> 4;
            sum_nibble_low = num1_nibble_low + num2_nibble_low + carry;
            if (sum_nibble_low >= 10)
            {
              sum_nibble_low = sum_nibble_low - 10;
              carry = 1;
            }
            else
            {
              carry = 0;
            }
            sum_nibble_high = num1_nibble_high + num2_nibble_high + carry;
            if (sum_nibble_high >= 10)
            {
              sum_nibble_high = sum_nibble_high - 10;
              carry = 1;
            }
            else
            {
              carry = 0;
            }
            sum_packed_byte = (sum_nibble_high << 4) + sum_nibble_low;
            sum = packed_string_integer_append_two_digits (sum, sum_packed_byte);
          }
// **********************************************************
// * Add num1 and num2 digits at the highest digit position *
// **********************************************************
          num1_packed_byte = temp_num1_integer_component->packed_number_block[i];
          num2_packed_byte = temp_num2_integer_component->packed_number_block[i];
          if (num1_highest_digit_position > num2_highest_digit_position)
          {
            if (highest_nibble_position == hi)
            {
              num1_nibble_low  = num1_packed_byte & 0x0f;
              num1_nibble_high = (num1_packed_byte & 0xf0) >> 4;
              num2_nibble_low  = num2_packed_byte & 0x0f;
              num2_nibble_high = (num2_packed_byte & 0xf0) >> 4;
              sum_nibble_low = num1_nibble_low + num2_nibble_low + carry;
              if (sum_nibble_low >= 10)
              {
                sum_nibble_low = sum_nibble_low - 10;
                carry = 1;
              }
              else
              {
                carry = 0;
              }
              sum_nibble_high = num1_nibble_high + num2_nibble_high + carry;
              if (sum_nibble_high >= 10)
              {
                sum_nibble_high = sum_nibble_high - 10;
                carry = 1;
              }
              else
              {
                carry = 0;
              }
              sum_packed_byte = (sum_nibble_high << 4) + sum_nibble_low;
              sum = packed_string_integer_append_two_digits (sum, sum_packed_byte);
            }
            else
            {
              if (highest_nibble_position == lo)
              {
                num1_nibble_low  = num1_packed_byte & 0x0f;
                num2_nibble_low  = num2_packed_byte & 0x0f;
                sum_nibble_low = num1_nibble_low + num2_nibble_low + carry;
                if (sum_nibble_low >= 10)
                {
                  sum_nibble_low = sum_nibble_low - 10;
                  carry = 1;
                }
                else
                {
                  carry = 0;
                }
                sum = packed_string_integer_append_one_digit (sum, sum_nibble_low);
                num1_nibble_high = (num1_packed_byte & 0xf0) >> 4;
                sum_nibble_high = num1_nibble_high + carry;
                if (sum_nibble_high >= 10)
                {
                  sum_nibble_high = sum_nibble_high - 10;
                  carry = 1;
                }
                else
                {
                  carry = 0;
                }
                sum = packed_string_integer_append_one_digit (sum, sum_nibble_high);
              }
            }
            i++;
            while (i < num1_highest_digit_position)
            {
              num1_packed_byte = temp_num1_integer_component->packed_number_block[i];
              num1_nibble_low  = num1_packed_byte & 0x0f;
              num1_nibble_high = (num1_packed_byte & 0xf0) >> 4;
              sum_nibble_low = num1_nibble_low + carry;
              if (sum_nibble_low >= 10)
              {
                sum_nibble_low = sum_nibble_low - 10;
                carry = 1;
              }
              else
              {
                carry = 0;
              }
              sum_nibble_high = num1_nibble_high + carry;
              if (sum_nibble_high >= 10)
              {
                sum_nibble_high = sum_nibble_high - 10;
                carry = 1;
              }
              else
              {
                carry = 0;
              }
              sum_packed_byte = (sum_nibble_high << 4) + sum_nibble_low;
              sum = packed_string_integer_append_two_digits (sum, sum_packed_byte);
              i++;
            }
            num1_packed_byte = temp_num1_integer_component->packed_number_block[i];
            if (temp_num1_integer_component->highest_nibble_position == hi)
            {
              num1_nibble_low  = num1_packed_byte & 0x0f;
              num1_nibble_high = (num1_packed_byte & 0xf0) >> 4;
              sum_nibble_low = num1_nibble_low + carry;
              if (sum_nibble_low >= 10)
              {
                sum_nibble_low = sum_nibble_low - 10;
                carry = 1;
              }
              else
              {
                carry = 0;
              }
              sum_nibble_high = num1_nibble_high + carry;
              if (sum_nibble_high >= 10)
              {
                sum_nibble_high = sum_nibble_high - 10;
                carry = 1;
              }
              else
              {
                carry = 0;
              }
              sum_packed_byte = (sum_nibble_high << 4) + sum_nibble_low;
              sum = packed_string_integer_append_two_digits (sum, sum_packed_byte);
            } 
            else
            {
              if (temp_num1_integer_component->highest_nibble_position == lo)
              {
                num1_nibble_low  = num1_packed_byte & 0x0f;
                sum_nibble_low = num1_nibble_low + carry;
                if (sum_nibble_low >= 10)
                {
                  sum_nibble_low = sum_nibble_low - 10;
                  carry = 1;
                }
                else
                {
                  carry = 0;
                }
                sum = packed_string_integer_append_one_digit (sum, sum_nibble_low);
              }
              else
              {
                printf ("Error in _packed_string_integer_add_both_numbers_same_sign(): highest_nibble_position undefined for temp_num1_integer_component->highest_nibble_position. Exiting now.\n");
                exit (EXIT_FAILURE);
              }
            }
          }
          else
          {
            if (num2_highest_digit_position > num1_highest_digit_position)
            {
              if (highest_nibble_position == hi)
              {
                num1_nibble_low  = num1_packed_byte & 0x0f;
                num1_nibble_high = (num1_packed_byte & 0xf0) >> 4;
                num2_nibble_low  = num2_packed_byte & 0x0f;
                num2_nibble_high = (num2_packed_byte & 0xf0) >> 4;
                sum_nibble_low = num1_nibble_low + num2_nibble_low + carry;
                if (sum_nibble_low >= 10)
                {
                  sum_nibble_low = sum_nibble_low - 10;
                  carry = 1;
                }
                else
                {
                  carry = 0;
                }
                sum_nibble_high = num1_nibble_high + num2_nibble_high + carry;
                if (sum_nibble_high >= 10)
                {
                  sum_nibble_high = sum_nibble_high - 10;
                  carry = 1;
                }
                else
                {
                  carry = 0;
                }
                sum_packed_byte = (sum_nibble_high << 4) + sum_nibble_low;
                sum = packed_string_integer_append_two_digits (sum, sum_packed_byte);
              }
              else
              {
                if (highest_nibble_position == lo)
                {
                  num1_nibble_low = num1_packed_byte & 0x0f;
                  num2_nibble_low = num2_packed_byte & 0x0f;
                  sum_nibble_low  = num1_nibble_low + num2_nibble_low + carry;
                  if (sum_nibble_low >= 10)
                  {
                    sum_nibble_low = sum_nibble_low - 10;
                    carry = 1;
                  }
                  else
                  {
                    carry = 0;
                  }
                  num2_nibble_high = (num2_packed_byte & 0xf0) >> 4;
                  sum_nibble_high = num2_nibble_high + carry;
                  if (sum_nibble_high >= 10)
                  {
                    sum_nibble_high = sum_nibble_high - 10;
                    carry = 1;
                  }
                  else
                  {
                    carry = 0;
                  }
                  sum_packed_byte = (sum_nibble_high << 4) + sum_nibble_low;
                  sum = packed_string_integer_append_two_digits (sum, sum_packed_byte);
                }
              }
              i++;
              while (i < num2_highest_digit_position)
              {
                num2_packed_byte = temp_num2_integer_component->packed_number_block[i];
                num2_nibble_low  = num2_packed_byte & 0x0f;
                num2_nibble_high = (num2_packed_byte & 0xf0) >> 4;
                sum_nibble_low = num2_nibble_low + carry;
                if (sum_nibble_low >= 10)
                {
                  sum_nibble_low = sum_nibble_low - 10;
                  carry = 1;
                }
                else
                {
                  carry = 0;
                }
                sum_nibble_high = num2_nibble_high + carry;
                if (sum_nibble_high >= 10)
                {
                  sum_nibble_high = sum_nibble_high - 10;
                  carry = 1;
                }
                else
                {
                  carry = 0;
                }
                sum_packed_byte = (sum_nibble_high << 4) + sum_nibble_low;
                sum = packed_string_integer_append_two_digits (sum, sum_packed_byte);
                i++;
              }
              num2_packed_byte = temp_num2_integer_component->packed_number_block[i];
              if (temp_num2_integer_component->highest_nibble_position == hi)
              {
                num2_nibble_low  = num2_packed_byte & 0x0f;
                num2_nibble_high = (num2_packed_byte & 0xf0) >> 4;
                sum_nibble_low = num2_nibble_low + carry;
                if (sum_nibble_low >= 10)
                {
                  sum_nibble_low = sum_nibble_low - 10;
                  carry = 1;
                }
                else
                {
                  carry = 0;
                }
                sum_nibble_high = num2_nibble_high + carry;
                if (sum_nibble_high >= 10)
                {
                  sum_nibble_high = sum_nibble_high - 10;
                  carry = 1;
                }
                else
                {
                  carry = 0;
                }
                sum_packed_byte = (sum_nibble_high << 4) + sum_nibble_low;
                sum = packed_string_integer_append_two_digits (sum, sum_packed_byte);
              } 
              else
              {
                if (temp_num2_integer_component->highest_nibble_position == lo)
                {
                  num2_nibble_low  = num2_packed_byte & 0x0f;
                  sum_nibble_low = num2_nibble_low + carry;
                  if (sum_nibble_low >= 10)
                  {
                    sum_nibble_low = sum_nibble_low - 10;
                    carry = 1;
                  }
                  else
                  {
                    carry = 0;
                  }
                  sum = packed_string_integer_append_one_digit (sum, sum_nibble_low);
                }
                else
                {
                  printf ("Error in _packed_string_integer_add_both_numbers_same_sign(): highest_nibble_position undefined for temp_num2_integer_component->highest_nibble_position. Exiting now.\n");
                  exit (EXIT_FAILURE);
                }
              }
            }
            else
            {
              if (num1_highest_digit_position == num2_highest_digit_position)
              {
                if ((temp_num1_integer_component->highest_nibble_position == hi) && (temp_num2_integer_component->highest_nibble_position == hi))
                {
                  num1_packed_byte = temp_num1_integer_component->packed_number_block[i];
                  num2_packed_byte = temp_num2_integer_component->packed_number_block[i];
                  num1_nibble_low  = num1_packed_byte & 0x0f;
                  num1_nibble_high = (num1_packed_byte & 0xf0) >> 4;
                  num2_nibble_low  = num2_packed_byte & 0x0f;
                  num2_nibble_high = (num2_packed_byte & 0xf0) >> 4;
                  sum_nibble_low = num1_nibble_low + num2_nibble_low + carry;
                  if (sum_nibble_low >= 10)
                  {
                    sum_nibble_low = sum_nibble_low - 10;
                    carry = 1;
                  }
                  else
                  {
                    carry = 0;
                  }
                  sum_nibble_high = num1_nibble_high + num2_nibble_high + carry;
                  if (sum_nibble_high >= 10)
                  {
                    sum_nibble_high = sum_nibble_high - 10;
                    carry = 1;
                  }
                  else
                  {
                    carry = 0;
                  }
                  sum_packed_byte = (sum_nibble_high << 4) + sum_nibble_low;
                  sum = packed_string_integer_append_two_digits (sum, sum_packed_byte);
                }
                else
                {
                  if ((temp_num1_integer_component->highest_nibble_position == hi) && (temp_num2_integer_component->highest_nibble_position == lo))
                  {
                    num1_packed_byte = temp_num1_integer_component->packed_number_block[i];
                    num2_packed_byte = temp_num2_integer_component->packed_number_block[i];
                    num1_nibble_low  = num1_packed_byte & 0x0f;
                    num1_nibble_high = (num1_packed_byte & 0xf0) >> 4;
                    num2_nibble_low  = num2_packed_byte & 0x0f;
                    sum_nibble_low = num1_nibble_low + num2_nibble_low + carry;
                    if (sum_nibble_low >= 10)
                    {
                      sum_nibble_low = sum_nibble_low - 10;
                      carry = 1;
                    }
                    else
                    {
                      carry = 0;
                    }
                    sum_nibble_high = num1_nibble_high + carry;
                    if (sum_nibble_high >= 10)
                    {
                      sum_nibble_high = sum_nibble_high - 10;
                      carry = 1;
                    }
                    else
                    {
                      carry = 0;
                    }
                    sum_packed_byte = (sum_nibble_high << 4) + sum_nibble_low;
                    sum = packed_string_integer_append_two_digits (sum, sum_packed_byte);
                  }
                  else
                  {
                    if ((temp_num1_integer_component->highest_nibble_position == lo) && (temp_num2_integer_component->highest_nibble_position == hi))
                    {
                      num1_packed_byte = temp_num1_integer_component->packed_number_block[i];
                      num2_packed_byte = temp_num2_integer_component->packed_number_block[i];
                      num1_nibble_low  = num1_packed_byte & 0x0f;
                      num1_nibble_high = 0;
                      num2_nibble_low  = num2_packed_byte & 0x0f;
                      num2_nibble_high = (num2_packed_byte & 0xf0) >> 4;
                      sum_nibble_low = num1_nibble_low + num2_nibble_low + carry;
                      if (sum_nibble_low >= 10)
                      {
                        sum_nibble_low = sum_nibble_low - 10;
                        carry = 1;
                      }
                      else
                      {
                        carry = 0;
                      }
                      sum_nibble_high = num2_nibble_high + carry;
                      if (sum_nibble_high >= 10)
                      {
                        sum_nibble_high = sum_nibble_high - 10;
                        carry = 1;
                      }
                      else
                      {
                        carry = 0;
                      }
                      sum_packed_byte = (sum_nibble_high << 4) + sum_nibble_low;
                      sum = packed_string_integer_append_two_digits (sum, sum_packed_byte);
                    }
                    else
                    {
                      if ((temp_num1_integer_component->highest_nibble_position == lo) && (temp_num2_integer_component->highest_nibble_position == lo))
                      {
                        num1_packed_byte = temp_num1_integer_component->packed_number_block[i];
                        num2_packed_byte = temp_num2_integer_component->packed_number_block[i];
                        num1_nibble_low  = num1_packed_byte & 0x0f;
                        num2_nibble_low  = num2_packed_byte & 0x0f;
                        sum_nibble_low = num1_nibble_low + num2_nibble_low + carry;
                        if (sum_nibble_low >= 10)
                        {
                          sum_nibble_low = sum_nibble_low - 10;
                          carry = 1;
                        }
                        else
                        {
                          carry = 0;
                        }
                        sum = packed_string_integer_append_one_digit (sum, sum_nibble_low);
                      }
                      else
                      {
                        printf ("Error in _packed_string_integer_add_both_numbers_same_sign(): highest_nibble_position undefined for num1 or num2 nibble_positions. Exiting now.\n");
                        exit (EXIT_FAILURE);
                      }
                    }
                  }
                }
              }
            }
          }
        } 
        else
        {
          printf ("Error in _packed_string_integer_add_both_numbers_same_sign(): highest digit position for either num1 or num2 exceeds MAX_PACKED_NUMBER_BLOCK_SIZE. Exiting now.\n");
          exit (EXIT_FAILURE);
        }
        temp_num1_integer_component = temp_num1_integer_component->next_number_block;
        temp_num2_integer_component = temp_num2_integer_component->next_number_block;
      }
// ********************************************************************************************
// * num1 and num2 could be different lengths. If num1 or num2 end, I must copy the remaining *
// * contents of the other number into the sum (result). I also must consider a set carry as  *
// * well.                                                                                    *
// ********************************************************************************************
      while (temp_num1_integer_component != NULL)
      {
        if ((temp_num1_integer_component->highest_digit_position >= 0) && (temp_num1_integer_component->highest_digit_position < MAX_PACKED_NUMBER_BLOCK_SIZE))
        {
          for (i = 0; i < temp_num1_integer_component->highest_digit_position; i++)
          {
            num1_packed_byte = temp_num1_integer_component->packed_number_block[i];
            num1_nibble_low  = num1_packed_byte & 0x0f;
            num1_nibble_high = (num1_packed_byte & 0xf0) >> 4;
            sum_nibble_low  = num1_nibble_low + carry;
            if (sum_nibble_low >= 10)
            {
              sum_nibble_low = sum_nibble_low - 10;
              carry = 1;
            }
            else
            {
              carry = 0;
            }
            sum_nibble_high = num1_nibble_high + carry;
            if (sum_nibble_high >= 10)
            {
              sum_nibble_high = sum_nibble_high - 10;
              carry = 1;
            }
            else
            {
              carry = 0;
            }
            sum_packed_byte = (sum_nibble_high << 4) + sum_nibble_low;
            sum = packed_string_integer_append_two_digits (sum, sum_packed_byte);
          }
          num1_packed_byte = temp_num1_integer_component->packed_number_block[i];
          if (temp_num1_integer_component->highest_nibble_position == hi)
          {
            num1_nibble_low  = num1_packed_byte & 0x0f;
            num1_nibble_high = (num1_packed_byte & 0xf0) >> 4;
            sum_nibble_low  = num1_nibble_low + carry;
            if (sum_nibble_low >= 10)
            {
              sum_nibble_low = sum_nibble_low - 10;
              carry = 1;
            }
            else
            {
              carry = 0;
            }
            sum_nibble_high = num1_nibble_high + carry;
            if (sum_nibble_high >= 10)
            {
              sum_nibble_high = sum_nibble_high - 10;
              carry = 1;
            }
            else
            {
              carry = 0;
            }
            sum_packed_byte = (sum_nibble_high << 4) + sum_nibble_low;
            sum = packed_string_integer_append_two_digits (sum, sum_packed_byte);
          }
          else
          {
            if (temp_num1_integer_component->highest_nibble_position == lo)
            {
              num1_nibble_low  = num1_packed_byte & 0x0f;
              sum_nibble_low  = num1_nibble_low + carry;
              if (sum_nibble_low >= 10)
              {
                sum_nibble_low = sum_nibble_low - 10;
                carry = 1;
              }
              else
              {
                carry = 0;
              }
              sum = packed_string_integer_append_one_digit (sum, sum_nibble_low);
            }
            else
            {
              printf ("Error in _packed_string_integer_add_both_numbers_same_sign(): highest_nibble_position undefined for temp_num1_integer_component->highest_nibble_position. Exiting now.\n");
              exit (EXIT_FAILURE);
            }
          }
        }
        else
        {
          printf ("Error in _packed_string_integer_add_both_numbers_same_sign(): highest digit position for num1 exceeds MAX_PACKED_NUMBER_BLOCK_SIZE. Exiting now.\n");
          exit (EXIT_FAILURE);
        }
        temp_num1_integer_component = temp_num1_integer_component->next_number_block;
      }
// ********************************************************************************************
// * num1 and num2 could be different lengths. If num1 or num2 end, I must copy the remaining *
// * contents of the other number into the sum (result). I also must consider a set carry as  *
// * well.                                                                                    *
// ********************************************************************************************
      while (temp_num2_integer_component != NULL)
      {
        if ((temp_num2_integer_component->highest_digit_position >= 0) && (temp_num2_integer_component->highest_digit_position < MAX_PACKED_NUMBER_BLOCK_SIZE))
        {
          for (i = 0; i < temp_num2_integer_component->highest_digit_position; i++)
          {
            num2_packed_byte = temp_num2_integer_component->packed_number_block[i];
            num2_nibble_low  = num2_packed_byte & 0x0f;
            num2_nibble_high = (num2_packed_byte & 0xf0) >> 4;
            sum_nibble_low = num2_nibble_low + carry;
            if (sum_nibble_low >= 10)
            {
              sum_nibble_low = sum_nibble_low - 10;
              carry = 1;
            }
            else
            {
              carry = 0;
            }
            sum_nibble_high = num2_nibble_high + carry;
            if (sum_nibble_high >= 10)
            {
              sum_nibble_high = sum_nibble_high - 10;
              carry = 1;
            }
            else
            {
              carry = 0;
            }
            sum_packed_byte = (sum_nibble_high << 4) + sum_nibble_low;
            sum = packed_string_integer_append_two_digits (sum, sum_packed_byte);
          }
          num2_packed_byte = temp_num2_integer_component->packed_number_block[i];
          if (temp_num2_integer_component->highest_nibble_position == hi)
          {
            num2_nibble_low  = num2_packed_byte & 0x0f;
            num2_nibble_high = (num2_packed_byte & 0xf0) >> 4;
            sum_nibble_low = num2_nibble_low + carry;
            if (sum_nibble_low >= 10)
            {
              sum_nibble_low = sum_nibble_low - 10;
              carry = 1;
            }
            else
            {
              carry = 0;
            }
            sum_nibble_high = num2_nibble_high + carry;
            if (sum_nibble_high >= 10)
            {
              sum_nibble_high = sum_nibble_high - 10;
              carry = 1;
            }
            else
            {
              carry = 0;
            }
            sum_packed_byte = (sum_nibble_high << 4) + sum_nibble_low;
            sum = packed_string_integer_append_two_digits (sum, sum_packed_byte);
          }
          else
          {
            if (temp_num2_integer_component->highest_nibble_position == lo)
            {
              num2_nibble_low  = num2_packed_byte & 0x0f;
              sum_nibble_low = num2_nibble_low + carry;
              if (sum_nibble_low >= 10)
              {
                sum_nibble_low = sum_nibble_low - 10;
                carry = 1;
              }
              else
              {
                carry = 0;
              }
              sum = packed_string_integer_append_one_digit (sum, sum_nibble_low);
            }
            else
            {
              printf ("Error in _packed_string_integer_add_both_numbers_same_sign(): highest_nibble_position undefined for temp_num2_integer_component->highest_nibble_position. Exiting now.\n");
              exit (EXIT_FAILURE);
            }
          }
        }
        else
        {
          printf ("Error in _packed_string_integer_add_both_numbers_same_sign(): highest digit position for num2 exceeds MAX_PACKED_NUMBER_BLOCK_SIZE. Exiting now.\n");
          exit (EXIT_FAILURE);
        }
        temp_num2_integer_component = temp_num2_integer_component->next_number_block;
      }
      if (carry == 1)
      {
        sum_packed_byte = 1;
        sum = packed_string_integer_append_one_digit (sum, sum_packed_byte);
      }
// ***************************************************************************
// * IF we made it this far without errors, then set status flag to success. *
// ***************************************************************************
      sum = packed_string_integer_set_status_flag (sum, NONE);
    }
    else
    {
      if ((num1->left_of_decimal != NULL) && (num2->left_of_decimal == NULL))
      {
        if (num2->sign == zero)
        {
          sum = packed_string_integer_copy_number (sum, num1);
          sum = packed_string_integer_set_status_flag (sum, NONE);
        }
      }
      else
      {
        if ((num1->left_of_decimal == NULL) && (num2->left_of_decimal != NULL))
        {
          if (num1->sign == zero)
          {
            sum = packed_string_integer_copy_number (sum, num2);
            sum = packed_string_integer_set_status_flag (sum, NONE);
          }
        }
      }
    }
  }
  return sum;
}




// *********************************************************************************
// * packed_string_integer_add                                                     *
// *                                                                               *
// * This is the main subroutine to call when adding two string-based integers.    *
// * Upon success, a stringint number is returned. Upon failure, NULL is returned. *
// *********************************************************************************
psint * packed_string_integer_add (psint *sum, psint *num1, psint *num2)
{
  psint *temp_num1, *temp_num2;
  int sign_of_both_numbers_is_same, greater_number;

// *************************************************************************
// * Release any previously used memory otherwise we'd have a memory leak. *
// *************************************************************************
  if (sum != NULL)
  {
    sum = packed_string_integer_component_release_memory (sum); // release the LEFT of DECIMAL number component (if exists) since initializing to zero requires LEFT of DECIMAL number component to be NULL;
  }
  temp_num1 = NULL;
  temp_num2 = NULL;
  sign_of_both_numbers_is_same = FALSE;
  if ((num1 != NULL) && (num2 != NULL))
  {
    if (((num1->sign == positive) && (num2->sign == positive)) ||
        ((num1->sign == zero)     && (num2->sign == zero))     ||
        ((num1->sign == negative) && (num2->sign == negative)))
    {
      sign_of_both_numbers_is_same = TRUE;
    }
    if (sign_of_both_numbers_is_same)
    {
// *************************************************************************************************************
// * No point iterating over two numbers if both numbers are zero. Make quick work and just assign sum a zero. *
// *************************************************************************************************************
      if (num1->sign != zero)
      {
        sum = _packed_string_integer_add_both_numbers_same_sign (sum, num1, num2);
        sum = packed_string_integer_set_sign (sum, num1->sign);
      }
      else
      {
        sum = packed_string_integer_initialize_to_zero (sum);
      }
    }
    else
    {
// **************************************************************************************************************************
// * When one of the numbers is zero and the other number is positive, process the numbers exactly like same-sign addition. *
// **************************************************************************************************************************
      if (((num1->sign == positive) && (num2->sign == zero))      ||
          ((num1->sign == zero)     && (num2->sign == positive)))  
      {
        sum = _packed_string_integer_add_both_numbers_same_sign (sum, num1, num2);
        sum = packed_string_integer_set_sign (sum, positive);
      }
      else
      {
// **************************************************************************************************************************
// * When one of the numbers is zero and the other number is negative, process the numbers exactly like same-sign addition. *
// **************************************************************************************************************************
        if (((num1->sign == zero)     && (num2->sign == negative)) ||
            ((num1->sign == negative) && (num2->sign == zero)))
        {
          sum = _packed_string_integer_add_both_numbers_same_sign (sum, num1, num2);
          sum = packed_string_integer_set_sign (sum, negative);
        }
        else
        {
// ********************************************************************
// * One of the numbers is positive and the other number is negative. *
// ********************************************************************
          if ((num1->sign == negative) && (num2->sign == positive))
          {
            temp_num1 = packed_string_integer_copy_number (temp_num1, num1);
            temp_num1 = packed_string_integer_set_sign (temp_num1, positive);
            greater_number = packed_string_integer_determine_absolute_value_larger_of_two_integers (temp_num1, num2);
            switch (greater_number)
            {
              case 1: // temp_num1 is greater than num2.
                sum = _packed_string_integer_subtract_both_numbers_same_sign (sum, temp_num1, num2);
                sum = packed_string_integer_set_sign (sum, negative); // Since num1 was originally negative, need to ensure sum (result) is negative.
              break;
              case 0: // temp_num1 is equal to num2.
                sum = packed_string_integer_initialize_to_zero (sum);
              break;
              case -1: // temp_num1 is less than num2.
                sum = _packed_string_integer_subtract_both_numbers_same_sign (sum, num2, temp_num1);
                sum = packed_string_integer_set_sign (sum, positive); 
              break;
              default:
                printf ("ERROR: packed_string_integer_determine_absolute_value_larger_of_two_integers returned an error.\n");
                exit (1);
              break;
            }
            temp_num1 = packed_string_integer_release_memory (temp_num1);
          }
          else
          {
            if ((num1->sign == positive) && (num2->sign == negative))
            {
              temp_num2 = packed_string_integer_copy_number (temp_num2, num2);
              greater_number = packed_string_integer_determine_absolute_value_larger_of_two_integers (num1, temp_num2);
              switch (greater_number)
              {
                case 1: // num1 is greater than temp_num2.
                  sum = _packed_string_integer_subtract_both_numbers_same_sign (sum, num1, temp_num2);
                  sum = packed_string_integer_set_sign (sum, positive); // Since num1 was originally positive, need to ensure sum (result) is positive.
                break;
                case 0: // num1 is equal to temp_num2.
                  sum = packed_string_integer_initialize_to_zero (sum);
                break;
                case -1: // num1 is less than temp_num2.
                  sum = _packed_string_integer_subtract_both_numbers_same_sign (sum, temp_num2, num1);
                  sum = packed_string_integer_set_sign (sum, negative); 
                break;
                default:
                  printf ("ERROR: packed_string_integer_determine_absolute_value_larger_of_two_integers returned an error.\n");
                  exit (1);
                break;
              }   
              temp_num2 = packed_string_integer_release_memory (temp_num2);
            }
          }
        }
      }
    }
  }
  return sum;
}




// ****************************************************************************************
// * _packed_string_integer_subtract_both_numbers_same_sign                               *
// *                                                                                      *
// * This is an internal library (denoted by an initial underscore in the function name). *
// ****************************************************************************************
psint * _packed_string_integer_subtract_both_numbers_same_sign (psint *difference, psint *num1, psint *num2)
{
  psnc *temp_num1_integer_component, *temp_num2_integer_component;
  unsigned char carry, num1_packed_byte, num2_packed_byte, num1_nibble_low, num2_nibble_low, num1_nibble_high, num2_nibble_high, byte, done;
  char difference_nibble_low, difference_nibble_high;
  long long int i, num1_highest_digit_position, num2_highest_digit_position, highest_digit_position;
  enum occupied_nibble highest_nibble_position;
  digit_stack_node *temp_digit_stack, *digit_stack;

// *************************************************************************
// * Release any previously used memory otherwise we'd have a memory leak. *
// *************************************************************************
  if (difference != NULL)
  {
    difference = packed_string_integer_component_release_memory (difference); // release the LEFT of DECIMAL number component (if exists) since initializing to zero requires LEFT of DECIMAL number component to be NULL;
  }
  carry = 0;
  digit_stack = NULL;
  temp_digit_stack = NULL;
  if ((num1 != NULL) && (num2 != NULL))
  {
    if ((num1->left_of_decimal != NULL) && (num2->left_of_decimal != NULL))
    {
      temp_num1_integer_component = num1->left_of_decimal;
      temp_num2_integer_component = num2->left_of_decimal;
      while ((temp_num1_integer_component != NULL) && (temp_num2_integer_component != NULL)) 
      {
        num1_highest_digit_position = temp_num1_integer_component->highest_digit_position;
        num2_highest_digit_position = temp_num2_integer_component->highest_digit_position;
        if ((num1_highest_digit_position >= 0) && (num1_highest_digit_position < MAX_PACKED_NUMBER_BLOCK_SIZE) &&
            (num2_highest_digit_position >= 0) && (num2_highest_digit_position < MAX_PACKED_NUMBER_BLOCK_SIZE))
        {
          if (num1_highest_digit_position < num2_highest_digit_position)
          {
            highest_digit_position = temp_num1_integer_component->highest_digit_position;
            highest_nibble_position = temp_num1_integer_component->highest_nibble_position;
          }
          else
          {
            if (num1_highest_digit_position > num2_highest_digit_position)
            {
              highest_digit_position = temp_num2_integer_component->highest_digit_position;
              highest_nibble_position = temp_num2_integer_component->highest_nibble_position;
            }
            else
            {
              if (num1_highest_digit_position == num2_highest_digit_position)
              {
                highest_digit_position = num1_highest_digit_position;
                if ((temp_num1_integer_component->highest_nibble_position == hi) && (temp_num2_integer_component->highest_nibble_position == hi))
                {
                  highest_nibble_position = hi;
                }
                else
                {
                  if ((temp_num1_integer_component->highest_nibble_position == hi) && (temp_num2_integer_component->highest_nibble_position == lo))
                  {
                    highest_nibble_position = lo;
                  }
                  else
                  {
                    if ((temp_num1_integer_component->highest_nibble_position == lo) && (temp_num2_integer_component->highest_nibble_position == hi))
                    {
                      highest_nibble_position = lo;
                    }
                    else
                    {
                      if ((temp_num1_integer_component->highest_nibble_position == lo) && (temp_num2_integer_component->highest_nibble_position == lo))
                      {
                        highest_nibble_position = lo;
                      }
                      else
                      {
                        printf ("Error in _packed_string_integer_subtract_both_numbers_same_sign(): failed to determine highest digit nibble position for num1 and num2. Exiting now.\n");
                        exit (EXIT_FAILURE);
                      }
                    }
                  }
                }
              }
              else
              {
                printf ("Error in _packed_string_integer_subtract_both_numbers_same_sign(): failed to determine highest digit position for num1 and num2. Exiting now.\n");
                exit (EXIT_FAILURE);
              }
            }
          }
          for (i = 0; i < highest_digit_position; i++)
          {
            num1_nibble_high = 0;
            num2_nibble_high = 0;
            num1_nibble_low  = 0;
            num2_nibble_low  = 0;
// *************************************************************************
// * Two Binary Coded Decimal (BCD) 4-bit digits are packed in each byte.  *
// * Unpack the bytes into lower and upper nibbles.                        *
// *************************************************************************
            //printf ("i = %llu, num1->highest_digit_position = %lld\n", i, temp_num1_integer_component->highest_digit_position);
            //printf ("i = %llu, num2->highest_digit_position = %lld\n", i, temp_num2_integer_component->highest_digit_position);
            num1_packed_byte = temp_num1_integer_component->packed_number_block[i];
            num2_packed_byte = temp_num2_integer_component->packed_number_block[i];
            num1_nibble_low  = num1_packed_byte & 0x0f;
            num1_nibble_high = (num1_packed_byte & 0xf0) >> 4;
            num2_nibble_low  = num2_packed_byte & 0x0f;
            num2_nibble_high = (num2_packed_byte & 0xf0) >> 4;
            difference_nibble_low = num1_nibble_low - num2_nibble_low - carry;
            if (difference_nibble_low < 0)
            {
              difference_nibble_low = difference_nibble_low + 10;
              carry = 1;
            }
            else
            {
              carry = 0;
            }
            temp_digit_stack = push_digit_stack (temp_digit_stack, difference_nibble_low + '0');
            difference_nibble_high = num1_nibble_high - num2_nibble_high - carry;
            if (difference_nibble_high < 0)
            {
              difference_nibble_high = difference_nibble_high + 10;
              carry = 1;
            }
            else
            {
              carry = 0;
            }
            temp_digit_stack = push_digit_stack (temp_digit_stack, difference_nibble_high + '0');
          }
// **********************************************************
// * Add num1 and num2 digits at the highest digit position *
// **********************************************************
          num1_packed_byte = temp_num1_integer_component->packed_number_block[i];
          num2_packed_byte = temp_num2_integer_component->packed_number_block[i];
          if (num1_highest_digit_position > num2_highest_digit_position)
          {
            if (highest_nibble_position == hi)
            {
              num1_nibble_low  = num1_packed_byte & 0x0f;
              num1_nibble_high = (num1_packed_byte & 0xf0) >> 4;
              num2_nibble_low  = num2_packed_byte & 0x0f;
              num2_nibble_high = (num2_packed_byte & 0xf0) >> 4;
              difference_nibble_low = num1_nibble_low - num2_nibble_low - carry;
              if (difference_nibble_low < 0)
              {
                difference_nibble_low = difference_nibble_low + 10;
                carry = 1;
              }
              else
              {
                carry = 0;
              }
              temp_digit_stack = push_digit_stack (temp_digit_stack, difference_nibble_low + '0');
              difference_nibble_high = num1_nibble_high - num2_nibble_high - carry;
              if (difference_nibble_high < 0)
              {
                difference_nibble_high = difference_nibble_high + 10;
                carry = 1;
              }
              else
              {
                carry = 0;
              }
              temp_digit_stack = push_digit_stack (temp_digit_stack, difference_nibble_high + '0');
            }
            else
            {
              if (highest_nibble_position == lo)
              {
                num1_nibble_low  = num1_packed_byte & 0x0f;
                num2_nibble_low  = num2_packed_byte & 0x0f;
                difference_nibble_low = num1_nibble_low - num2_nibble_low - carry;
                if (difference_nibble_low < 0)
                {
                  difference_nibble_low = difference_nibble_low + 10;
                  carry = 1;
                }
                else
                {
                  carry = 0;
                }
                temp_digit_stack = push_digit_stack (temp_digit_stack, difference_nibble_low + '0');
                num1_nibble_high = (num1_packed_byte & 0xf0) >> 4;
                difference_nibble_high = num1_nibble_high - carry;
                if (difference_nibble_high < 0)
                {
                  difference_nibble_high = difference_nibble_high + 10;
                  carry = 1;
                }
                else
                {
                  carry = 0;
                }
                temp_digit_stack = push_digit_stack (temp_digit_stack, difference_nibble_high + '0');
              }
            }
            i++;
            while (i < num1_highest_digit_position)
            {
              num1_packed_byte = temp_num1_integer_component->packed_number_block[i];
              num1_nibble_low  = num1_packed_byte & 0x0f;
              num1_nibble_high = (num1_packed_byte & 0xf0) >> 4;
              difference_nibble_low = num1_nibble_low - carry;
              if (difference_nibble_low < 0)
              {
                difference_nibble_low = difference_nibble_low + 10;
                carry = 1;
              }
              else
              {
                carry = 0;
              }
              temp_digit_stack = push_digit_stack (temp_digit_stack, difference_nibble_low + '0');
              difference_nibble_high = num1_nibble_high - carry;
              if (difference_nibble_high < 0)
              {
                difference_nibble_high = difference_nibble_high + 10;
                carry = 1;
              }
              else
              {
                carry = 0;
              }
              temp_digit_stack = push_digit_stack (temp_digit_stack, difference_nibble_high + '0');
              i++;
            }
            num1_packed_byte = temp_num1_integer_component->packed_number_block[i];
            if (temp_num1_integer_component->highest_nibble_position == hi)
            {
              num1_nibble_low  = num1_packed_byte & 0x0f;
              num1_nibble_high = (num1_packed_byte & 0xf0) >> 4;
              difference_nibble_low = num1_nibble_low - carry;
              if (difference_nibble_low < 0)
              {
                difference_nibble_low = difference_nibble_low + 10;
                carry = 1;
              }
              else
              {
                carry = 0;
              }
              temp_digit_stack = push_digit_stack (temp_digit_stack, difference_nibble_low + '0');
              difference_nibble_high = num1_nibble_high - carry;
              if (difference_nibble_high < 0)
              {
                difference_nibble_high = difference_nibble_high + 10;
                carry = 1;
              }
              else
              {
                carry = 0;
              }
              temp_digit_stack = push_digit_stack (temp_digit_stack, difference_nibble_high + '0');
            } 
            else
            {
              if (temp_num1_integer_component->highest_nibble_position == lo)
              {
                num1_nibble_low  = num1_packed_byte & 0x0f;
                difference_nibble_low = num1_nibble_low - carry;
                if (difference_nibble_low < 0)
                {
                  difference_nibble_low = difference_nibble_low + 10;
                  carry = 1;
                }
                else
                {
                  carry = 0;
                }
                temp_digit_stack = push_digit_stack (temp_digit_stack, difference_nibble_low + '0');
              }
              else
              {
                printf ("Error in _packed_string_integer_subtract_both_numbers_same_sign(): highest_nibble_position undefined for temp_num1_integer_component->highest_nibble_position. Exiting now.\n");
                exit (EXIT_FAILURE);
              }
            }
          }
          else
          {
            if (num2_highest_digit_position > num1_highest_digit_position)
            {
              if (highest_nibble_position == hi)
              {
                num1_nibble_low  = num1_packed_byte & 0x0f;
                num1_nibble_high = (num1_packed_byte & 0xf0) >> 4;
                num2_nibble_low  = num2_packed_byte & 0x0f;
                num2_nibble_high = (num2_packed_byte & 0xf0) >> 4;
                difference_nibble_low = num1_nibble_low - num2_nibble_low - carry;
                if (difference_nibble_low < 0)
                {
                  difference_nibble_low = difference_nibble_low + 10;
                  carry = 1;
                }
                else
                {
                  carry = 0;
                }
                temp_digit_stack = push_digit_stack (temp_digit_stack, difference_nibble_low + '0');
                difference_nibble_high = num1_nibble_high - num2_nibble_high - carry;
                if (difference_nibble_high < 0)
                {
                  difference_nibble_high = difference_nibble_high + 10;
                  carry = 1;
                }
                else
                {
                  carry = 0;
                }
                temp_digit_stack = push_digit_stack (temp_digit_stack, difference_nibble_high + '0');
              }
              else
              {
                if (highest_nibble_position == lo)
                {
                  num1_nibble_low = num1_packed_byte & 0x0f;
                  num2_nibble_low = num2_packed_byte & 0x0f;
                  difference_nibble_low  = num1_nibble_low - num2_nibble_low - carry;
                  if (difference_nibble_low < 0)
                  {
                    difference_nibble_low = difference_nibble_low + 10;
                    carry = 1;
                  }
                  else
                  {
                    carry = 0;
                  }
                  temp_digit_stack = push_digit_stack (temp_digit_stack, difference_nibble_low + '0');
                  num2_nibble_high = (num2_packed_byte & 0xf0) >> 4;
                  difference_nibble_high = num2_nibble_high - carry;
                  if (difference_nibble_high < 0)
                  {
                    difference_nibble_high = difference_nibble_high + 10;
                    carry = 1;
                  }
                  else
                  {
                    carry = 0;
                  }
                  temp_digit_stack = push_digit_stack (temp_digit_stack, difference_nibble_high + '0');
                }
              }
              i++;
              while (i < num2_highest_digit_position)
              {
                num2_packed_byte = temp_num2_integer_component->packed_number_block[i];
                num2_nibble_low  = num2_packed_byte & 0x0f;
                num2_nibble_high = (num2_packed_byte & 0xf0) >> 4;
                difference_nibble_low = num2_nibble_low - carry;
                if (difference_nibble_low < 0)
                {
                  difference_nibble_low = difference_nibble_low + 10;
                  carry = 1;
                }
                else
                {
                  carry = 0;
                }
                temp_digit_stack = push_digit_stack (temp_digit_stack, difference_nibble_low + '0');
                difference_nibble_high = num2_nibble_high - carry;
                if (difference_nibble_high < 0)
                {
                  difference_nibble_high = difference_nibble_high + 10;
                  carry = 1;
                }
                else
                {
                  carry = 0;
                }
                temp_digit_stack = push_digit_stack (temp_digit_stack, difference_nibble_high + '0');
                i++;
              }
              num2_packed_byte = temp_num2_integer_component->packed_number_block[i];
              if (temp_num2_integer_component->highest_nibble_position == hi)
              {
                num2_nibble_low  = num2_packed_byte & 0x0f;
                num2_nibble_high = (num2_packed_byte & 0xf0) >> 4;
                difference_nibble_low = num2_nibble_low - carry;
                if (difference_nibble_low < 0)
                {
                  difference_nibble_low = difference_nibble_low + 10;
                  carry = 1;
                }
                else
                {
                  carry = 0;
                }
                temp_digit_stack = push_digit_stack (temp_digit_stack, difference_nibble_low + '0');
                difference_nibble_high = num2_nibble_high - carry;
                if (difference_nibble_high < 0)
                {
                  difference_nibble_high = difference_nibble_high + 10;
                  carry = 1;
                }
                else
                {
                  carry = 0;
                }
                temp_digit_stack = push_digit_stack (temp_digit_stack, difference_nibble_high + '0');
              } 
              else
              {
                if (temp_num2_integer_component->highest_nibble_position == lo)
                {
                  num2_nibble_low  = num2_packed_byte & 0x0f;
                  difference_nibble_low = num2_nibble_low - carry;
                  if (difference_nibble_low < 0)
                  {
                    difference_nibble_low = difference_nibble_low + 10;
                    carry = 1;
                  }
                  else
                  {
                    carry = 0;
                  }
                  temp_digit_stack = push_digit_stack (temp_digit_stack, difference_nibble_low + '0');
                }
                else
                {
                  printf ("Error in _packed_string_integer_subtract_both_numbers_same_sign(): highest_nibble_position undefined for temp_num2_integer_component->highest_nibble_position. Exiting now.\n");
                  exit (EXIT_FAILURE);
                }
              }
            }
            else
            {
              if (num1_highest_digit_position == num2_highest_digit_position)
              {
                if ((temp_num1_integer_component->highest_nibble_position == hi) && (temp_num2_integer_component->highest_nibble_position == hi))
                {
                  num1_packed_byte = temp_num1_integer_component->packed_number_block[i];
                  num2_packed_byte = temp_num2_integer_component->packed_number_block[i];
                  num1_nibble_low  = num1_packed_byte & 0x0f;
                  num1_nibble_high = (num1_packed_byte & 0xf0) >> 4;
                  num2_nibble_low  = num2_packed_byte & 0x0f;
                  num2_nibble_high = (num2_packed_byte & 0xf0) >> 4;
                  difference_nibble_low = num1_nibble_low - num2_nibble_low - carry;
                  if (difference_nibble_low < 0)
                  {
                    difference_nibble_low = difference_nibble_low + 10;
                    carry = 1;
                  }
                  else
                  {
                    carry = 0;
                  }
                  temp_digit_stack = push_digit_stack (temp_digit_stack, difference_nibble_low + '0');
                  difference_nibble_high = num1_nibble_high - num2_nibble_high - carry;
                  if (difference_nibble_high < 0)
                  {
                    difference_nibble_high = difference_nibble_high + 10;
                    carry = 1;
                  }
                  else
                  {
                    carry = 0;
                  }
                  temp_digit_stack = push_digit_stack (temp_digit_stack, difference_nibble_high + '0');
                }
                else
                {
                  if ((temp_num1_integer_component->highest_nibble_position == hi) && (temp_num2_integer_component->highest_nibble_position == lo))
                  {
                    num1_packed_byte = temp_num1_integer_component->packed_number_block[i];
                    num2_packed_byte = temp_num2_integer_component->packed_number_block[i];
                    num1_nibble_low  = num1_packed_byte & 0x0f;
                    num1_nibble_high = (num1_packed_byte & 0xf0) >> 4;
                    num2_nibble_low  = num2_packed_byte & 0x0f;
                    difference_nibble_low = num1_nibble_low - num2_nibble_low - carry;
                    if (difference_nibble_low < 0)
                    {
                      difference_nibble_low = difference_nibble_low + 10;
                      carry = 1;
                    }
                    else
                    {
                      carry = 0;
                    }
                    temp_digit_stack = push_digit_stack (temp_digit_stack, difference_nibble_low + '0');
                    difference_nibble_high = num1_nibble_high - carry;
                    if (difference_nibble_high < 0)
                    {
                      difference_nibble_high = difference_nibble_high + 10;
                      carry = 1;
                    }
                    else
                    {
                      carry = 0;
                    }
                    temp_digit_stack = push_digit_stack (temp_digit_stack, difference_nibble_high + '0');
                  }
                  else
                  {
                    if ((temp_num1_integer_component->highest_nibble_position == lo) && (temp_num2_integer_component->highest_nibble_position == hi))
                    {
                      num1_packed_byte = temp_num1_integer_component->packed_number_block[i];
                      num2_packed_byte = temp_num2_integer_component->packed_number_block[i];
                      num1_nibble_low  = num1_packed_byte & 0x0f;
                      num1_nibble_high = 0;
                      num2_nibble_low  = num2_packed_byte & 0x0f;
                      num2_nibble_high = (num2_packed_byte & 0xf0) >> 4;
                      difference_nibble_low = num1_nibble_low - num2_nibble_low - carry;
                      if (difference_nibble_low < 0)
                      {
                        difference_nibble_low = difference_nibble_low + 10;
                        carry = 1;
                      }
                      else
                      {
                        carry = 0;
                      }
                      temp_digit_stack = push_digit_stack (temp_digit_stack, difference_nibble_low + '0');
                      difference_nibble_high = num2_nibble_high - carry;
                      if (difference_nibble_high < 0)
                      {
                        difference_nibble_high = difference_nibble_high + 10;
                        carry = 1;
                      }
                      else
                      {
                        carry = 0;
                      }
                      temp_digit_stack = push_digit_stack (temp_digit_stack, difference_nibble_high + '0');
                    }
                    else
                    {
                      if ((temp_num1_integer_component->highest_nibble_position == lo) && (temp_num2_integer_component->highest_nibble_position == lo))
                      {
                        num1_packed_byte = temp_num1_integer_component->packed_number_block[i];
                        num2_packed_byte = temp_num2_integer_component->packed_number_block[i];
                        num1_nibble_low  = num1_packed_byte & 0x0f;
                        num2_nibble_low  = num2_packed_byte & 0x0f;
                        difference_nibble_low = num1_nibble_low - num2_nibble_low - carry;
                        if (difference_nibble_low < 0)
                        {
                          difference_nibble_low = difference_nibble_low + 10;
                          carry = 1;
                        }
                        else
                        {
                          carry = 0;
                        }
                        temp_digit_stack = push_digit_stack (temp_digit_stack, difference_nibble_low + '0');
                      }
                      else
                      {
                        printf ("Error in _packed_string_integer_subtract_both_numbers_same_sign(): highest_nibble_position undefined for num1 or num2 nibble_positions. Exiting now.\n");
                        exit (EXIT_FAILURE);
                      }
                    }
                  }
                }
              }
            }
          }
        } 
        else
        {
          printf ("Error in _packed_string_integer_subtract_both_numbers_same_sign(): highest digit position for either num1 or num2 exceeds MAX_PACKED_NUMBER_BLOCK_SIZE. Exiting now.\n");
          exit (EXIT_FAILURE);
        }
        temp_num1_integer_component = temp_num1_integer_component->next_number_block;
        temp_num2_integer_component = temp_num2_integer_component->next_number_block;
      }
// ********************************************************************************************
// * num1 and num2 could be different lengths. If num1 or num2 end, I must copy the remaining *
// * contents of the other number into the difference (result). I also must consider a set carry as  *
// * well.                                                                                    *
// ********************************************************************************************
      while (temp_num1_integer_component != NULL)
      {
        if ((temp_num1_integer_component->highest_digit_position >= 0) && (temp_num1_integer_component->highest_digit_position < MAX_PACKED_NUMBER_BLOCK_SIZE))
        {
          for (i = 0; i < temp_num1_integer_component->highest_digit_position; i++)
          {
            num1_packed_byte = temp_num1_integer_component->packed_number_block[i];
            num1_nibble_low  = num1_packed_byte & 0x0f;
            num1_nibble_high = (num1_packed_byte & 0xf0) >> 4;
            difference_nibble_low  = num1_nibble_low - carry;
            if (difference_nibble_low < 0)
            {
              difference_nibble_low = difference_nibble_low + 10;
              carry = 1;
            }
            else
            {
              carry = 0;
            }
            temp_digit_stack = push_digit_stack (temp_digit_stack, difference_nibble_low + '0');
            difference_nibble_high = num1_nibble_high - carry;
            if (difference_nibble_high < 0)
            {
              difference_nibble_high = difference_nibble_high + 10;
              carry = 1;
            }
            else
            {
              carry = 0;
            }
            temp_digit_stack = push_digit_stack (temp_digit_stack, difference_nibble_high + '0');
          }
          num1_packed_byte = temp_num1_integer_component->packed_number_block[i];
          if (temp_num1_integer_component->highest_nibble_position == hi)
          {
            num1_nibble_low  = num1_packed_byte & 0x0f;
            num1_nibble_high = (num1_packed_byte & 0xf0) >> 4;
            difference_nibble_low  = num1_nibble_low - carry;
            if (difference_nibble_low < 0)
            {
              difference_nibble_low = difference_nibble_low + 10;
              carry = 1;
            }
            else
            {
              carry = 0;
            }
            temp_digit_stack = push_digit_stack (temp_digit_stack, difference_nibble_low + '0');
            difference_nibble_high = num1_nibble_high - carry;
            if (difference_nibble_high < 0)
            {
              difference_nibble_high = difference_nibble_high + 10;
              carry = 1;
            }
            else
            {
              carry = 0;
            }
            temp_digit_stack = push_digit_stack (temp_digit_stack, difference_nibble_high + '0');
          }
          else
          {
            if (temp_num1_integer_component->highest_nibble_position == lo)
            {
              num1_nibble_low  = num1_packed_byte & 0x0f;
              difference_nibble_low  = num1_nibble_low - carry;
              if (difference_nibble_low < 0)
              {
                difference_nibble_low = difference_nibble_low + 10;
                carry = 1;
              }
              else
              {
                carry = 0;
              }
              temp_digit_stack = push_digit_stack (temp_digit_stack, difference_nibble_low + '0');
            }
            else
            {
              printf ("Error in _packed_string_integer_subtract_both_numbers_same_sign(): highest_nibble_position undefined for temp_num1_integer_component->highest_nibble_position. Exiting now.\n");
              exit (EXIT_FAILURE);
            }
          }
        }
        else
        {
          printf ("Error in _packed_string_integer_subtract_both_numbers_same_sign(): highest digit position for num1 exceeds MAX_PACKED_NUMBER_BLOCK_SIZE. Exiting now.\n");
          exit (EXIT_FAILURE);
        }
        temp_num1_integer_component = temp_num1_integer_component->next_number_block;
      }
// ********************************************************************************************
// * num1 and num2 could be different lengths. If num1 or num2 end, I must copy the remaining *
// * contents of the other number into the difference (result). I also must consider a set carry as  *
// * well.                                                                                    *
// ********************************************************************************************
      while (temp_num2_integer_component != NULL)
      {
        if ((temp_num2_integer_component->highest_digit_position >= 0) && (temp_num2_integer_component->highest_digit_position < MAX_PACKED_NUMBER_BLOCK_SIZE))
        {
          for (i = 0; i < temp_num2_integer_component->highest_digit_position; i++)
          {
            num2_packed_byte = temp_num2_integer_component->packed_number_block[i];
            num2_nibble_low  = num2_packed_byte & 0x0f;
            num2_nibble_high = (num2_packed_byte & 0xf0) >> 4;
            difference_nibble_low = num2_nibble_low - carry;
            if (difference_nibble_low < 0)
            {
              difference_nibble_low = difference_nibble_low + 10;
              carry = 1;
            }
            else
            {
              carry = 0;
            }
            temp_digit_stack = push_digit_stack (temp_digit_stack, difference_nibble_low + '0');
            difference_nibble_high = num2_nibble_high - carry;
            if (difference_nibble_high < 0)
            {
              difference_nibble_high = difference_nibble_high + 10;
              carry = 1;
            }
            else
            {
              carry = 0;
            }
            temp_digit_stack = push_digit_stack (temp_digit_stack, difference_nibble_high + '0');
          }
          num2_packed_byte = temp_num2_integer_component->packed_number_block[i];
          if (temp_num2_integer_component->highest_nibble_position == hi)
          {
            num2_nibble_low  = num2_packed_byte & 0x0f;
            num2_nibble_high = (num2_packed_byte & 0xf0) >> 4;
            difference_nibble_low = num2_nibble_low - carry;
            if (difference_nibble_low < 0)
            {
              difference_nibble_low = difference_nibble_low + 10;
              carry = 1;
            }
            else
            {
              carry = 0;
            }
            temp_digit_stack = push_digit_stack (temp_digit_stack, difference_nibble_low + '0');
            difference_nibble_high = num2_nibble_high - carry;
            if (difference_nibble_high < 0)
            {
              difference_nibble_high = difference_nibble_high + 10;
              carry = 1;
            }
            else
            {
              carry = 0;
            }
            temp_digit_stack = push_digit_stack (temp_digit_stack, difference_nibble_high + '0');
          }
          else
          {
            if (temp_num2_integer_component->highest_nibble_position == lo)
            {
              num2_nibble_low  = num2_packed_byte & 0x0f;
              difference_nibble_low = num2_nibble_low - carry;
              if (difference_nibble_low < 0)
              {
                difference_nibble_low = difference_nibble_low + 10;
                carry = 1;
              }
              else
              {
                carry = 0;
              }
              temp_digit_stack = push_digit_stack (temp_digit_stack, difference_nibble_low + '0');
            }
            else
            {
              printf ("Error in _packed_string_integer_subtract_both_numbers_same_sign(): highest_nibble_position undefined for temp_num2_integer_component->highest_nibble_position. Exiting now.\n");
              exit (EXIT_FAILURE);
            }
          }
        }
        else
        {
          printf ("Error in _packed_string_integer_subtract_both_numbers_same_sign(): highest digit position for num2 exceeds MAX_PACKED_NUMBER_BLOCK_SIZE. Exiting now.\n");
          exit (EXIT_FAILURE);
        }
        temp_num2_integer_component = temp_num2_integer_component->next_number_block;
      }
      if (carry == 1)
      {
        temp_digit_stack = push_digit_stack (temp_digit_stack, '1');
      }
// *************************************************************************
// * Now remove LEADING zeros to find the most significant non-zero digit. *
// *                                                                       *
// * Example of removing leading zeros: 00000123 becomes 123               *
// *************************************************************************
      done = FALSE;
      while ((temp_digit_stack != NULL) && (!done))
      {
        byte = top_digit_stack (temp_digit_stack);
        if (byte > '0')
        {
          done = TRUE;
        }
        else
        {
          temp_digit_stack = pop_digit_stack (temp_digit_stack);
        }
      }
// ****************************************************************************************************************************
// * Digits are in reverse order on the temp_digit_stack. Now invert order on another stack before inserting LEFT of DECIMAL. *
// ****************************************************************************************************************************
      while (temp_digit_stack != NULL)
      {
        byte = top_digit_stack (temp_digit_stack);
        digit_stack = push_digit_stack (digit_stack, byte);
        temp_digit_stack = pop_digit_stack (temp_digit_stack);
      }
// ******************************************************************
// * Digits are now in proper order to be inserted LEFT of DECIMAL. *
// ******************************************************************
      while (digit_stack != NULL)
      {
        byte = top_digit_stack (digit_stack);
        byte = byte - '0';
        difference = packed_string_integer_append_one_digit (difference, byte);
        digit_stack = pop_digit_stack (digit_stack);
      }
// *************************************************************************
// * Since we made it this far without errors, set status flag to success. *
// *************************************************************************
      difference = packed_string_integer_set_status_flag (difference, NONE);
    }
    else
    {
      if ((num1->left_of_decimal != NULL) && (num2->left_of_decimal == NULL))
      {
        if (num2->sign == zero)
        {
          difference = packed_string_integer_copy_number (difference, num1);
          difference = packed_string_integer_set_status_flag (difference, NONE);
        }
      }
      else
      {
        if ((num1->left_of_decimal == NULL) && (num2->left_of_decimal != NULL))
        {
          if (num1->sign == zero)
          {
            difference = packed_string_integer_copy_number (difference, num2);
            difference = packed_string_integer_set_status_flag (difference, NONE);
          }
        }
      }
    }
  }
  return difference;
}




// ***********************************************************************************
// * packed_string_integer_subtract                                                  *
// *                                                                                 *
// * This is the main subroutine to call when subtracting two string-based integers. *
// * Upon success, a stringint number is returned. Upon failure, NULL is returned.   *
// ***********************************************************************************
psint * packed_string_integer_subtract (psint *difference, psint *num1, psint *num2)
{
  psint *temp_num1, *temp_num2;
  int greater_number;

  temp_num1 = NULL;
  temp_num2 = NULL;
// *************************************************************************
// * Release any previously used memory otherwise we'd have a memory leak. *
// *************************************************************************
  if (difference != NULL)
  {
    difference = packed_string_integer_component_release_memory (difference); // release the LEFT of DECIMAL number component (if exists) since initializing to zero requires LEFT of DECIMAL number component to be NULL;
  }
  if ((num1 != NULL) && (num2 != NULL))
  {
    if (num1->sign == positive)
    {
      if (num2->sign == positive)
      {
        greater_number = packed_string_integer_determine_absolute_value_larger_of_two_integers (num1, num2);
        switch (greater_number)
        {
          case 1: // num1 is greater than num2. Difference will be positive since num1 is greater than num2.
            difference = _packed_string_integer_subtract_both_numbers_same_sign (difference, num1, num2);
            difference = packed_string_integer_set_sign (difference, positive);
          break;
          case 0: // num1 is equal to num2. Difference will be zero.
            difference = packed_string_integer_initialize_to_zero (difference);
          break;
          case -1: // num1 is less than num2. Difference will be negative since num2 is greater than num1. 
            difference = _packed_string_integer_subtract_both_numbers_same_sign (difference, num2, num1);
            difference = packed_string_integer_set_sign (difference, negative);
          break;
          default:
            printf ("ERROR: packed_string_integer_determine_absolute_value_larger_of_two_integers returned an error.\n");
            exit (1);
          break;
        }
      }
      else
      {
// ***********************************************************************
// * Subtracting from a negative number is the same as adding the number *
// ***********************************************************************
        if (num2->sign == negative)
        {
          temp_num2 = packed_string_integer_copy_number (temp_num2, num2);
          temp_num2 = packed_string_integer_set_sign (temp_num2, positive);
          difference = _packed_string_integer_add_both_numbers_same_sign (difference, num1, temp_num2);
          difference = packed_string_integer_set_sign (difference, positive);
          temp_num2 = packed_string_integer_release_memory (temp_num2);
        }
        else
        {
          if (num2->sign == zero)
          {
            difference = packed_string_integer_copy_number (difference, num1);
          }
        }
      }
    }
    else
    {
      if (num1->sign == negative)
      {
        if (num2->sign == positive)
        {
// ***********************************************************************************************************
// * Subtracing num2 from num1 is like adding two negative numbers togeter and preserving the negative sign. *
// ***********************************************************************************************************
          temp_num1 = packed_string_integer_copy_number (temp_num1, num1);
          temp_num1 = packed_string_integer_set_sign (temp_num1, positive);
          difference = _packed_string_integer_add_both_numbers_same_sign (difference, temp_num1, num2);
          difference = packed_string_integer_set_sign (difference, negative);
          temp_num1 = packed_string_integer_release_memory (temp_num1);
        }
        else
        {
          if (num2->sign == negative)
          {
// ****************************************************************************************************************
// * Since num2 and num2 both have negative values, -num2 - (-num1) = -num2 + num1. The next step is to determine *
// * which absolute value of num1 and num2 is larger. Then perform a subtraction and set sign appropriately.      *
// ****************************************************************************************************************
            greater_number = packed_string_integer_determine_absolute_value_larger_of_two_integers (num1, num2);
            switch (greater_number)
            {
              case 1: // absolute_value(num1) > absolute_value(num2) 
                difference = _packed_string_integer_subtract_both_numbers_same_sign (difference, num1, num2);
                difference = packed_string_integer_set_sign (difference, negative);
              break;
              case 0: // abssolute_value(num1) == absolute_value(num2) 
                difference = packed_string_integer_initialize_to_zero (difference);
              break;
              case -1: // abssolute_value(num1) < absolute_value(num2) 
                difference = _packed_string_integer_subtract_both_numbers_same_sign (difference, num2, num1);
                difference = packed_string_integer_set_sign (difference, positive);
              break;
              default:
                printf ("ERROR: packed_string_integer_determine_absolute_value_larger_of_two_integers returned an error.\n");
                exit (1);
              break;
            }
          }
          else
          {
            if (num2->sign == zero)
            {
              difference = packed_string_integer_copy_number (difference, num1);
            }
          }
        }
      }
      else
      {
        if (num1->sign == zero)
        {
          if (num2->sign == positive)
          {
            difference = packed_string_integer_copy_number (difference, num2);
            difference = packed_string_integer_set_sign (difference, negative);
          }
          else
          {
            if (num2->sign == negative)
            {
              difference = packed_string_integer_copy_number (difference, num2);
              difference = packed_string_integer_set_sign (difference, positive);
            }
            else
            {
              if (num2->sign == zero)
              {
                difference = packed_string_integer_initialize_to_zero (difference);
              }
            }
          }
        }
      }
    }
  }
  return difference;
}




// ******************************************************************************************************************************************************
// * _packed_string_integer_decrement_one                                                                                                               *
// *                                                                                                                                                    *
// * This is an internal library. It should not be called directly. Instead, it should be called from the function: packed_string_integer_decrement_one *                        
// ******************************************************************************************************************************************************
psint * _packed_string_integer_decrement_one (psint *number)
{
  psint *difference;
  psnc *number_integer_component, *temp_num;
  long long int i;
  unsigned char borrow, number_packed_byte, number_nibble_low, number_nibble_high, difference_packed_byte;
  char difference_nibble_high, difference_nibble_low;
  int in_first_number_block;

  borrow = 0;
  in_first_number_block = TRUE;
  difference = NULL;
  number_integer_component = NULL;
  if (number != NULL)
  {
    if (number->left_of_decimal != NULL)
    {
      number_integer_component = number->left_of_decimal;
      number_packed_byte = number_integer_component->packed_number_block[0];
      number_nibble_low  = number_packed_byte & 0x0f;
      number_nibble_high = (number_packed_byte & 0xf0) >> 4;
      difference_nibble_low  = number_nibble_low - 1;
      if (difference_nibble_low < 0)
      {
        difference_nibble_low = difference_nibble_low + 10;
        borrow = 1;
      }
      difference_nibble_high = number_nibble_high - borrow;
      if  (difference_nibble_high < 0)
      {
        difference_nibble_high = difference_nibble_high + 10;
        borrow = 1;
      }
      else
      {
        borrow = 0;
      }
      difference_packed_byte = (difference_nibble_high << 4) + difference_nibble_low;
      difference = packed_string_integer_append_two_digits (difference, difference_packed_byte);
      temp_num = number->left_of_decimal;
      while (temp_num != NULL) 
      {
        if (in_first_number_block)
        {
          i = 1;
        }
        else
        {
          i = 0;
        }
        while (i < MAX_PACKED_NUMBER_BLOCK_SIZE)
        {
// *************************************************************************
// * Two Binary Coded Decimal (BCD) 4-bit digits are packed in each byte.  *
// * Unpack the bytes into lower and upper nibbles.                        *
// *************************************************************************
          number_packed_byte = temp_num->packed_number_block[i];
          number_nibble_low  = number_packed_byte & 0x0f;
          number_nibble_high = (number_packed_byte & 0xf0) >> 4;
          difference_nibble_low = number_nibble_low - borrow;
          if (difference_nibble_low < 0)
          {
            difference_nibble_low = difference_nibble_low + 10;
            borrow = 1;
          }
          else
          {
            borrow = 0;
          }
          difference_nibble_high = number_nibble_high - borrow;
          if  (difference_nibble_high < 0)
          {
            difference_nibble_high = difference_nibble_high + 10;
            borrow = 1;
          }
          else
          {
            borrow = 0;
          }
          difference_packed_byte = (difference_nibble_high << 4) + difference_nibble_low;
          difference = packed_string_integer_append_two_digits (difference, difference_packed_byte);
          i++;
        }
        in_first_number_block = FALSE;
        temp_num = temp_num->next_number_block;
      }
// ***************************************************************************************************************************
// * Check if we can reduce the amount of storage memory (number blocks) that are no longer needed after the subtraction.    *
// ***************************************************************************************************************************
    }
  }
  return difference;
}




// *********************************************************************************************************************
// * packed_string_integer_decrement_one                                                                               *
// *                                                                                                                   *
// * This function is designed to be a fast alternative for decrementing packed, string-based integers. Specifically,  *
// * it is meant to be faster than calling packed_string_integer_subtract with two packed string-based integers        *
// * paramemters.                                                                                                      *
// *                                                                                                                   *
// * INPUT: a packed string-based integer                                                                              *
// * OUTPUT: a packed string-based integer decremented by one OR null on error.                                        *
// *********************************************************************************************************************
psint * packed_string_integer_decrement_one (psint *number)
{
  psint *difference, *constant_one, *temp_number;
  int greater_number;

  temp_number  = NULL;
  constant_one = NULL;
  difference   = NULL;
  if (number != NULL)
  {
    if (number->left_of_decimal != NULL)
    {
      if (number->sign == positive)
      {
        greater_number = packed_string_integer_determine_absolute_value_number_greater_than_one (number);
        switch (greater_number)
        {
          case 1: // number > 1 : Difference will be positive.
            difference = _packed_string_integer_decrement_one (number);
            difference = packed_string_integer_set_sign (difference, positive);
          break;
          case 0: // number == 1 : Difference will be zero.
            difference = packed_string_integer_initialize_to_zero (difference);
          break;
          case -1: // number < 1 : This should be impossible since the number has a positive sign.
            printf ("ERROR: stringint_decrement one failed. Input number has positive sign yet is less than one.\n");
            exit (1);
          break;
          default:
            printf ("ERROR: packed_string_integer_decrement_one failed. Unable to determine if input number is greater than one.\n");
            exit (1);
          break;
        }
      }
      else
      {
        if (number->sign == negative)
        {
// ***********************************************************************************************************
// * Subtracing one from number is like adding two negative numbers togeter and preserving the negative sign. *
// ***********************************************************************************************************
          constant_one = packed_string_integer_set_value (constant_one, "1");
          temp_number  = packed_string_integer_copy_number (temp_number, number);
          temp_number  = packed_string_integer_set_sign (temp_number, positive);
          difference   = _packed_string_integer_add_both_numbers_same_sign (difference, temp_number, constant_one);
          difference   = packed_string_integer_set_sign (difference, negative);
          temp_number  = packed_string_integer_release_memory (temp_number);
          constant_one = packed_string_integer_release_memory (constant_one); 
        }
        else
        {
          if (number->sign == zero)
          {
            difference = packed_string_integer_set_value (difference, "-1");
          }
        }
      }
    }
  }
  return difference;
}




// *********************************************************************************************************************************************************
// * _packed_string_integer_multiply                                                                                                                       *
// *                                                                                                                                                       *
// * This is the internal subroutine that computes the actual multiplication of a packed string-based integer num1 and a packed string-based integer num2. *
// *                                                                                                                                                       *
// * This function should not be called directly. Instead, it should be called through subroutine packed_string_integer_multiply.                          *
// *********************************************************************************************************************************************************
psint * _packed_string_integer_multiply (psint *product, psint *num1, psint *num2)
{
  psint *temp_product, *sum, *temp_sum, *constant_one;
  psnc  *temp_num1_integer_component, *temp_num2_integer_component;;
  unsigned char carry, num1_packed_byte, num2_packed_byte, num1_nibble_low, num2_nibble_low, num1_nibble_high, num2_nibble_high, product_packed_byte;
  unsigned char product_nibble_high, product_nibble_low;
  long long int i, j, shift_left_counter;
  int product_is_greater_than_zero, greater_number;

// *************************************************************************
// * Release any previously used memory otherwise we'd have a memory leak. *
// *************************************************************************
  if (product != NULL)
  {
    product = packed_string_integer_component_release_memory (product); // release the LEFT of DECIMAL number component (if exists) since initializing to zero requires LEFT of DECIMAL number component to be NULL;
  }
  temp_num1_integer_component = NULL;
  temp_num2_integer_component = NULL;
  temp_product = NULL;
  temp_sum     = NULL;
  sum          = NULL;
  constant_one = NULL;
  sum = packed_string_integer_initialize_to_zero (sum);
  shift_left_counter = 0;
  constant_one = packed_string_integer_set_value (constant_one, "1");
  if ((num1 != NULL) && (num2 != NULL))
  {
    if ((num1->left_of_decimal != NULL) && (num2->left_of_decimal != NULL) && (constant_one != NULL))
    {
      temp_num2_integer_component = num2->left_of_decimal;
      while (temp_num2_integer_component != NULL)
      {
        if ((temp_num2_integer_component->highest_digit_position >= 0) && (temp_num2_integer_component->highest_digit_position < MAX_PACKED_NUMBER_BLOCK_SIZE))
        {
          for (i = 0; i < temp_num2_integer_component->highest_digit_position; i++)
          {
            num2_packed_byte = temp_num2_integer_component->packed_number_block[i];
            num2_nibble_low  = num2_packed_byte & 0x0f;
            num2_nibble_high = (num2_packed_byte & 0xf0) >> 4;
            product = packed_string_integer_component_release_memory (product);
            product_is_greater_than_zero = FALSE;
            carry = 0;
            //printf ("num2_nibble_high = %d, num2_nibble_low = %d\n\n", num2_nibble_high, num2_nibble_low);
            temp_num1_integer_component = num1->left_of_decimal;
            while (temp_num1_integer_component != NULL)
            {
              if ((temp_num1_integer_component->highest_digit_position >= 0) && (temp_num1_integer_component->highest_digit_position < MAX_PACKED_NUMBER_BLOCK_SIZE))
              {
                for (j = 0; j < temp_num1_integer_component->highest_digit_position; j++)
                {
                  num1_packed_byte = temp_num1_integer_component->packed_number_block[j];
                  num1_nibble_low  = num1_packed_byte & 0x0f;
                  num1_nibble_high = (num1_packed_byte & 0xf0) >> 4;
                  product_nibble_low = num1_nibble_low * num2_nibble_low + carry;
                  //printf ("num1_nibble_high = %d, num1_nibble_low = %d\n", num1_nibble_high, num1_nibble_low);
                  switch (product_nibble_low)
                  {
                    case 0:
                    case 1:
                    case 2:
                    case 3:
                    case 4:
                    case 5:
                    case 6:
                    case 7:
                    case 8:
                    case 9:
                      carry = 0;
                    break;
                    case 10:
                    case 11:
                    case 12:
                    case 13:
                    case 14:
                    case 15:
                    case 16:
                    case 17:
                    case 18:
                    case 19:
                      carry = 1;
                      product_nibble_low = product_nibble_low - 10;
                    break;
                    case 20:
                    case 21:
                    case 22:
                    case 23:
                    case 24:
                    case 25:
                    case 26:
                    case 27:
                    case 28:
                    case 29:
                      carry = 2;
                      product_nibble_low = product_nibble_low - 20;
                    break;
                    case 30:
                    case 31:
                    case 32:
                    case 33:
                    case 34:
                    case 35:
                    case 36:
                    case 37:
                    case 38:
                    case 39:
                      carry = 3;
                      product_nibble_low = product_nibble_low - 30;
                    break;
                    case 40:
                    case 41:
                    case 42:
                    case 43:
                    case 44:
                    case 45:
                    case 46:
                    case 47:
                    case 48:
                    case 49:
                      carry = 4;
                      product_nibble_low = product_nibble_low - 40;
                    break;
                    case 50:
                    case 51:
                    case 52:
                    case 53:
                    case 54:
                    case 55:
                    case 56:
                    case 57:
                    case 58:
                    case 59:
                      carry = 5;
                      product_nibble_low = product_nibble_low - 50;
                    break;
                    case 60:
                    case 61:
                    case 62:
                    case 63:
                    case 64:
                    case 65:
                    case 66:
                    case 67:
                    case 68:
                    case 69:
                      carry = 6;
                      product_nibble_low = product_nibble_low - 60;
                    break;
                    case 70:
                    case 71:
                    case 72:
                    case 73:
                    case 74:
                    case 75:
                    case 76:
                    case 77:
                    case 78:
                    case 79:
                      carry = 7;
                      product_nibble_low = product_nibble_low - 70;
                    break;         
                    case 80:
                    case 81:
                    case 82:
                    case 83:
                    case 84:
                    case 85:
                    case 86:
                    case 87:
                    case 88:
                    case 89:
                      carry = 8;
                      product_nibble_low = product_nibble_low - 80;
                    break;
                    default:
                      printf ("Error in _packed_string_integer_multiply: encounted an invalid digit during multiplication. Exiting now.\n");
                      exit (EXIT_FAILURE);
                    break;
                  }
                  product_nibble_high  = num1_nibble_high * num2_nibble_low + carry;
                  switch (product_nibble_high)
                  {
                    case 0:
                    case 1:
                    case 2:
                    case 3:
                    case 4:
                    case 5:
                    case 6:
                    case 7:
                    case 8:
                    case 9:
                      carry = 0;
                    break;
                    case 10:
                    case 11:
                    case 12:
                    case 13:
                    case 14:
                    case 15:
                    case 16:
                    case 17:
                    case 18:
                    case 19:
                      carry = 1;
                      product_nibble_high = product_nibble_high - 10;
                    break;
                    case 20:
                    case 21:
                    case 22:
                    case 23:
                    case 24:
                    case 25:
                    case 26:
                    case 27:
                    case 28:
                    case 29:
                      carry = 2;
                      product_nibble_high = product_nibble_high - 20;
                    break;
                    case 30:
                    case 31:
                    case 32:
                    case 33:
                    case 34:
                    case 35:
                    case 36:
                    case 37:
                    case 38:
                    case 39:
                      carry = 3;
                      product_nibble_high = product_nibble_high - 30;
                    break;
                    case 40:
                    case 41:
                    case 42:
                    case 43:
                    case 44:
                    case 45:
                    case 46:
                    case 47:
                    case 48:
                    case 49:
                      carry = 4;
                      product_nibble_high = product_nibble_high - 40;
                    break;
                    case 50:
                    case 51:
                    case 52:
                    case 53:
                    case 54:
                    case 55:
                    case 56:
                    case 57:
                    case 58:
                    case 59:
                      carry = 5;
                      product_nibble_high = product_nibble_high - 50;
                    break;
                    case 60:
                    case 61:
                    case 62:
                    case 63:
                    case 64:
                    case 65:
                    case 66:
                    case 67:
                    case 68:
                    case 69:
                      carry = 6;
                      product_nibble_high = product_nibble_high - 60;
                    break;
                    case 70:
                    case 71:
                    case 72:
                    case 73:
                    case 74:
                    case 75:
                    case 76:
                    case 77:
                    case 78:
                    case 79:
                      carry = 7;
                      product_nibble_high = product_nibble_high - 70;
                    break;         
                    case 80:
                    case 81:
                    case 82:
                    case 83:
                    case 84:
                    case 85:
                    case 86:
                    case 87:
                    case 88:
                    case 89:
                      carry = 8;
                      product_nibble_high = product_nibble_high - 80;
                    break;
                    default:
                      printf ("Error in _packed_string_integer_multiply: encounted an invalid digit during multiplication. Exiting now.\n");
                      exit (EXIT_FAILURE);
                    break;
                  }
                  product_packed_byte = (product_nibble_high << 4) + product_nibble_low;
                  if (product_packed_byte > 0)
                  {
                    product_is_greater_than_zero = TRUE;
                  }
                  product = packed_string_integer_append_two_digits (product, product_packed_byte);
                } // CLOSING STATEMENT BLOCK: for (j = 0; j < temp_num1_integer_component->highest_digit_position; j++)
// ***************************************************
// * Now process num1 at the highest digit position. *
// ***************************************************
                if (temp_num1_integer_component->highest_nibble_position == hi)
                {
                  num1_packed_byte = temp_num1_integer_component->packed_number_block[j];
                  num1_nibble_low  = num1_packed_byte & 0x0f;
                  num1_nibble_high = (num1_packed_byte & 0xf0) >> 4;
                  product_nibble_low = num1_nibble_low * num2_nibble_low + carry;
                  //printf ("num1_nibble_high = %d, num1_nibble_low = %d\n", num1_nibble_high, num1_nibble_low);
                  switch (product_nibble_low)
                  {
                    case 0:
                    case 1:
                    case 2:
                    case 3:
                    case 4:
                    case 5:
                    case 6:
                    case 7:
                    case 8:
                    case 9:
                      carry = 0;
                    break;
                    case 10:
                    case 11:
                    case 12:
                    case 13:
                    case 14:
                    case 15:
                    case 16:
                    case 17:
                    case 18:
                    case 19:
                      carry = 1;
                      product_nibble_low = product_nibble_low - 10;
                    break;
                    case 20:
                    case 21:
                    case 22:
                    case 23:
                    case 24:
                    case 25:
                    case 26:
                    case 27:
                    case 28:
                    case 29:
                      carry = 2;
                      product_nibble_low = product_nibble_low - 20;
                    break;
                    case 30:
                    case 31:
                    case 32:
                    case 33:
                    case 34:
                    case 35:
                    case 36:
                    case 37:
                    case 38:
                    case 39:
                      carry = 3;
                      product_nibble_low = product_nibble_low - 30;
                    break;
                    case 40:
                    case 41:
                    case 42:
                    case 43:
                    case 44:
                    case 45:
                    case 46:
                    case 47:
                    case 48:
                    case 49:
                      carry = 4;
                      product_nibble_low = product_nibble_low - 40;
                    break;
                    case 50:
                    case 51:
                    case 52:
                    case 53:
                    case 54:
                    case 55:
                    case 56:
                    case 57:
                    case 58:
                    case 59:
                      carry = 5;
                      product_nibble_low = product_nibble_low - 50;
                    break;
                    case 60:
                    case 61:
                    case 62:
                    case 63:
                    case 64:
                    case 65:
                    case 66:
                    case 67:
                    case 68:
                    case 69:
                      carry = 6;
                      product_nibble_low = product_nibble_low - 60;
                    break;
                    case 70:
                    case 71:
                    case 72:
                    case 73:
                    case 74:
                    case 75:
                    case 76:
                    case 77:
                    case 78:
                    case 79:
                      carry = 7;
                      product_nibble_low = product_nibble_low - 70;
                    break;         
                    case 80:
                    case 81:
                    case 82:
                    case 83:
                    case 84:
                    case 85:
                    case 86:
                    case 87:
                    case 88:
                    case 89:
                      carry = 8;
                      product_nibble_low = product_nibble_low - 80;
                    break;
                    default:
                      printf ("Error in _packed_string_integer_multiply: encounted an invalid digit during multiplication. Exiting now.\n");
                      exit (EXIT_FAILURE);
                    break;
                  }
                  product_nibble_high = num1_nibble_high * num2_nibble_low + carry;
                  switch (product_nibble_high)
                  {
                    case 0:
                    case 1:
                    case 2:
                    case 3:
                    case 4:
                    case 5:
                    case 6:
                    case 7:
                    case 8:
                    case 9:
                      carry = 0;
                    break;
                    case 10:
                    case 11:
                    case 12:
                    case 13:
                    case 14:
                    case 15:
                    case 16:
                    case 17:
                    case 18:
                    case 19:
                      carry = 1;
                      product_nibble_high = product_nibble_high - 10;
                    break;
                    case 20:
                    case 21:
                    case 22:
                    case 23:
                    case 24:
                    case 25:
                    case 26:
                    case 27:
                    case 28:
                    case 29:
                      carry = 2;
                      product_nibble_high = product_nibble_high - 20;
                    break;
                    case 30:
                    case 31:
                    case 32:
                    case 33:
                    case 34:
                    case 35:
                    case 36:
                    case 37:
                    case 38:
                    case 39:
                      carry = 3;
                      product_nibble_high = product_nibble_high - 30;
                    break;
                    case 40:
                    case 41:
                    case 42:
                    case 43:
                    case 44:
                    case 45:
                    case 46:
                    case 47:
                    case 48:
                    case 49:
                      carry = 4;
                      product_nibble_high = product_nibble_high - 40;
                    break;
                    case 50:
                    case 51:
                    case 52:
                    case 53:
                    case 54:
                    case 55:
                    case 56:
                    case 57:
                    case 58:
                    case 59:
                      carry = 5;
                      product_nibble_high = product_nibble_high - 50;
                    break;
                    case 60:
                    case 61:
                    case 62:
                    case 63:
                    case 64:
                    case 65:
                    case 66:
                    case 67:
                    case 68:
                    case 69:
                      carry = 6;
                      product_nibble_high = product_nibble_high - 60;
                    break;
                    case 70:
                    case 71:
                    case 72:
                    case 73:
                    case 74:
                    case 75:
                    case 76:
                    case 77:
                    case 78:
                    case 79:
                      carry = 7;
                      product_nibble_high = product_nibble_high - 70;
                    break;         
                    case 80:
                    case 81:
                    case 82:
                    case 83:
                    case 84:
                    case 85:
                    case 86:
                    case 87:
                    case 88:
                    case 89:
                      carry = 8;
                      product_nibble_high = product_nibble_high - 80;
                    break;
                    default:
                      printf ("Error in _packed_string_integer_multiply: encounted an invalid digit during multiplication. Exiting now.\n");
                      exit (EXIT_FAILURE);
      exit (EXIT_FAILURE);
                    break;
                  }
                  product_packed_byte = (product_nibble_high << 4) + product_nibble_low;
                  if (product_packed_byte > 0)
                  {
                    product_is_greater_than_zero = TRUE;
                  }
                  product = packed_string_integer_append_two_digits (product, product_packed_byte);
                }
                else
                {
                  if (temp_num1_integer_component->highest_nibble_position == lo)
                  {
                    num1_packed_byte = temp_num1_integer_component->packed_number_block[j];
                    num1_nibble_low  = num1_packed_byte & 0x0f;
// *********************************************************************
// * product_nibble_low  = num1_nibble_low  * num2_nibble_low + carry  *
// *********************************************************************
                    product_nibble_low = num1_nibble_low * num2_nibble_low + carry;
                    switch (product_nibble_low)
                    {
                      case 0:
                      case 1:
                      case 2:
                      case 3:
                      case 4:
                      case 5:
                      case 6:
                      case 7:
                      case 8:
                      case 9:
                        carry = 0;
                      break;
                      case 10:
                      case 11:
                      case 12:
                      case 13:
                      case 14:
                      case 15:
                      case 16:
                      case 17:
                      case 18:
                      case 19:
                        carry = 1;
                        product_nibble_low = product_nibble_low - 10;
                      break;
                      case 20:
                      case 21:
                      case 22:
                      case 23:
                      case 24:
                      case 25:
                      case 26:
                      case 27:
                      case 28:
                      case 29:
                        carry = 2;
                        product_nibble_low = product_nibble_low - 20;
                      break;
                      case 30:
                      case 31:
                      case 32:
                      case 33:
                      case 34:
                      case 35:
                      case 36:
                      case 37:
                      case 38:
                      case 39:
                        carry = 3;
                        product_nibble_low = product_nibble_low - 30;
                      break;
                      case 40:
                      case 41:
                      case 42:
                      case 43:
                      case 44:
                      case 45:
                      case 46:
                      case 47:
                      case 48:
                      case 49:
                        carry = 4;
                        product_nibble_low = product_nibble_low - 40;
                      break;
                      case 50:
                      case 51:
                      case 52:
                      case 53:
                      case 54:
                      case 55:
                      case 56:
                      case 57:
                      case 58:
                      case 59:
                        carry = 5;
                        product_nibble_low = product_nibble_low - 50;
                      break;
                      case 60:
                      case 61:
                      case 62:
                      case 63:
                      case 64:
                      case 65:
                      case 66:
                      case 67:
                      case 68:
                      case 69:
                        carry = 6;
                        product_nibble_low = product_nibble_low - 60;
                      break;
                      case 70:
                      case 71:
                      case 72:
                      case 73:
                      case 74:
                      case 75:
                      case 76:
                      case 77:
                      case 78:
                      case 79:
                        carry = 7;
                        product_nibble_low = product_nibble_low - 70;
                      break;         
                      case 80:
                      case 81:
                      case 82:
                      case 83:
                      case 84:
                      case 85:
                      case 86:
                      case 87:
                      case 88:
                      case 89:
                        carry = 8;
                        product_nibble_low = product_nibble_low - 80;
                      break;
                      default:
                        printf ("Error in _packed_string_integer_multiply: encounted an invalid digit during multiplication. Exiting now.\n");
                        exit (EXIT_FAILURE);
                      break;
                    }
                    product_packed_byte = product_nibble_low;
                    if (product_packed_byte > 0)
                    {
                      product_is_greater_than_zero = TRUE;
                    }
                    product = packed_string_integer_append_one_digit (product, product_packed_byte);
                  }
                  else
                  {
                    printf ("Internal error in _packed_string_integer_multiply(). temp_num1_integeR_component->highest_nibble_position is undefined. Exiting now.\n");
                    exit (EXIT_FAILURE);
                  }
                }
              }
              temp_num1_integer_component = temp_num1_integer_component->next_number_block;
            } 
            if (carry > 0)
            {
              product_packed_byte = carry;
              if (product_packed_byte > 0)
              {
                product_is_greater_than_zero = TRUE;
              }
              product = packed_string_integer_append_one_digit (product, product_packed_byte);
              carry = 0;
            }
            if (product_is_greater_than_zero)
            {     
              product = packed_string_integer_set_sign (product, positive);
            }
            temp_product = packed_string_integer_shift_digits_left (product, shift_left_counter); // product = temp_product * 10^i 
            if (temp_product != NULL)
            {
              greater_number = packed_string_integer_determine_absolute_value_larger_of_two_integers (temp_product, constant_one);
              if ((greater_number == 0) || (greater_number == 1)) // is temp_product greater than or equal to one? IF yes, then set sign on temp_product to positive.
              {
                temp_product = packed_string_integer_set_sign (temp_product, positive);
              }
              else
              {
                temp_product = packed_string_integer_initialize_to_zero (temp_product);
              }
            }
            else
            {
              temp_product = packed_string_integer_initialize_to_zero (temp_product);
            }
            temp_sum                = packed_string_integer_add (temp_sum, sum, temp_product);
            sum                     = packed_string_integer_component_release_memory (sum);
            sum                     = packed_string_integer_copy_number (sum, temp_sum);
            temp_product            = packed_string_integer_release_memory (temp_product);
            temp_sum                = packed_string_integer_release_memory (temp_sum);
            shift_left_counter++;
// ***********************************
// * Now process num2's high nibble. *
// ***********************************
            product = packed_string_integer_release_memory (product);
            product_is_greater_than_zero = FALSE;
            carry = 0;
            temp_num1_integer_component = num1->left_of_decimal;
            while (temp_num1_integer_component != NULL)
            {
              if ((temp_num1_integer_component->highest_digit_position >= 0) && (temp_num1_integer_component->highest_digit_position < MAX_PACKED_NUMBER_BLOCK_SIZE))
              {
                for (j = 0; j < temp_num1_integer_component->highest_digit_position; j++)
                {
                  num1_packed_byte = temp_num1_integer_component->packed_number_block[j];
                  num1_nibble_low  = num1_packed_byte & 0x0f;
                  num1_nibble_high = (num1_packed_byte & 0xf0) >> 4;
                  product_nibble_low = num1_nibble_low * num2_nibble_high + carry;
                  //printf ("num1_nibble_high = %d, num1_nibble_low = %d\n", num1_nibble_high, num1_nibble_low);
                  switch (product_nibble_low)
                  {
                    case 0:
                    case 1:
                    case 2:
                    case 3:
                    case 4:
                    case 5:
                    case 6:
                    case 7:
                    case 8:
                    case 9:
                      carry = 0;
                    break;
                    case 10:
                    case 11:
                    case 12:
                    case 13:
                    case 14:
                    case 15:
                    case 16:
                    case 17:
                    case 18:
                    case 19:
                      carry = 1;
                      product_nibble_low = product_nibble_low - 10;
                    break;
                    case 20:
                    case 21:
                    case 22:
                    case 23:
                    case 24:
                    case 25:
                    case 26:
                    case 27:
                    case 28:
                    case 29:
                      carry = 2;
                      product_nibble_low = product_nibble_low - 20;
                    break;
                    case 30:
                    case 31:
                    case 32:
                    case 33:
                    case 34:
                    case 35:
                    case 36:
                    case 37:
                    case 38:
                    case 39:
                      carry = 3;
                      product_nibble_low = product_nibble_low - 30;
                    break;
                    case 40:
                    case 41:
                    case 42:
                    case 43:
                    case 44:
                    case 45:
                    case 46:
                    case 47:
                    case 48:
                    case 49:
                      carry = 4;
                      product_nibble_low = product_nibble_low - 40;
                    break;
                    case 50:
                    case 51:
                    case 52:
                    case 53:
                    case 54:
                    case 55:
                    case 56:
                    case 57:
                    case 58:
                    case 59:
                      carry = 5;
                      product_nibble_low = product_nibble_low - 50;
                    break;
                    case 60:
                    case 61:
                    case 62:
                    case 63:
                    case 64:
                    case 65:
                    case 66:
                    case 67:
                    case 68:
                    case 69:
                      carry = 6;
                      product_nibble_low = product_nibble_low - 60;
                    break;
                    case 70:
                    case 71:
                    case 72:
                    case 73:
                    case 74:
                    case 75:
                    case 76:
                    case 77:
                    case 78:
                    case 79:
                      carry = 7;
                      product_nibble_low = product_nibble_low - 70;
                    break;         
                    case 80:
                    case 81:
                    case 82:
                    case 83:
                    case 84:
                    case 85:
                    case 86:
                    case 87:
                    case 88:
                    case 89:
                      carry = 8;
                      product_nibble_low = product_nibble_low - 80;
                    break;
                    default:
                      printf ("ERROR: encounted an invalid multiplication.\n");
                      exit(1);
                    break;
                  }
                  product_nibble_high  = num1_nibble_high * num2_nibble_high + carry;
                  switch (product_nibble_high)
                  {
                    case 0:
                    case 1:
                    case 2:
                    case 3:
                    case 4:
                    case 5:
                    case 6:
                    case 7:
                    case 8:
                    case 9:
                      carry = 0;
                    break;
                    case 10:
                    case 11:
                    case 12:
                    case 13:
                    case 14:
                    case 15:
                    case 16:
                    case 17:
                    case 18:
                    case 19:
                      carry = 1;
                      product_nibble_high = product_nibble_high - 10;
                    break;
                    case 20:
                    case 21:
                    case 22:
                    case 23:
                    case 24:
                    case 25:
                    case 26:
                    case 27:
                    case 28:
                    case 29:
                      carry = 2;
                      product_nibble_high = product_nibble_high - 20;
                    break;
                    case 30:
                    case 31:
                    case 32:
                    case 33:
                    case 34:
                    case 35:
                    case 36:
                    case 37:
                    case 38:
                    case 39:
                      carry = 3;
                      product_nibble_high = product_nibble_high - 30;
                    break;
                    case 40:
                    case 41:
                    case 42:
                    case 43:
                    case 44:
                    case 45:
                    case 46:
                    case 47:
                    case 48:
                    case 49:
                      carry = 4;
                      product_nibble_high = product_nibble_high - 40;
                    break;
                    case 50:
                    case 51:
                    case 52:
                    case 53:
                    case 54:
                    case 55:
                    case 56:
                    case 57:
                    case 58:
                    case 59:
                      carry = 5;
                      product_nibble_high = product_nibble_high - 50;
                    break;
                    case 60:
                    case 61:
                    case 62:
                    case 63:
                    case 64:
                    case 65:
                    case 66:
                    case 67:
                    case 68:
                    case 69:
                      carry = 6;
                      product_nibble_high = product_nibble_high - 60;
                    break;
                    case 70:
                    case 71:
                    case 72:
                    case 73:
                    case 74:
                    case 75:
                    case 76:
                    case 77:
                    case 78:
                    case 79:
                      carry = 7;
                      product_nibble_high = product_nibble_high - 70;
                    break;         
                    case 80:
                    case 81:
                    case 82:
                    case 83:
                    case 84:
                    case 85:
                    case 86:
                    case 87:
                    case 88:
                    case 89:
                      carry = 8;
                      product_nibble_high = product_nibble_high - 80;
                    break;
                    default:
                      printf ("ERROR: encounted an invalid multiplication.\n");
      exit (EXIT_FAILURE);
                    break;
                  }
                  product_packed_byte = (product_nibble_high << 4) + product_nibble_low;
                  if (product_packed_byte > 0)
                  {
                    product_is_greater_than_zero = TRUE;
                  }
                  product = packed_string_integer_append_two_digits (product, product_packed_byte);
                } // CLOSING STATEMENT BLOCK: for (j = 0; j < temp_num1_integer_component->highest_digit_position; j++)
// ***************************************************
// * Now process num1 at the highest digit position. *
// ***************************************************
                if (temp_num1_integer_component->highest_nibble_position == hi)
                {
                  num1_packed_byte = temp_num1_integer_component->packed_number_block[j];
                  num1_nibble_low  = num1_packed_byte & 0x0f;
                  num1_nibble_high = (num1_packed_byte & 0xf0) >> 4;
                  product_nibble_low = num1_nibble_low * num2_nibble_high + carry;
                  //printf ("num1_nibble_high = %d, num1_nibble_low = %d\n", num1_nibble_high, num1_nibble_low);
                  switch (product_nibble_low)
                  {
                    case 0:
                    case 1:
                    case 2:
                    case 3:
                    case 4:
                    case 5:
                    case 6:
                    case 7:
                    case 8:
                    case 9:
                      carry = 0;
                    break;
                    case 10:
                    case 11:
                    case 12:
                    case 13:
                    case 14:
                    case 15:
                    case 16:
                    case 17:
                    case 18:
                    case 19:
                      carry = 1;
                      product_nibble_low = product_nibble_low - 10;
                    break;
                    case 20:
                    case 21:
                    case 22:
                    case 23:
                    case 24:
                    case 25:
                    case 26:
                    case 27:
                    case 28:
                    case 29:
                      carry = 2;
                      product_nibble_low = product_nibble_low - 20;
                    break;
                    case 30:
                    case 31:
                    case 32:
                    case 33:
                    case 34:
                    case 35:
                    case 36:
                    case 37:
                    case 38:
                    case 39:
                      carry = 3;
                      product_nibble_low = product_nibble_low - 30;
                    break;
                    case 40:
                    case 41:
                    case 42:
                    case 43:
                    case 44:
                    case 45:
                    case 46:
                    case 47:
                    case 48:
                    case 49:
                      carry = 4;
                      product_nibble_low = product_nibble_low - 40;
                    break;
                    case 50:
                    case 51:
                    case 52:
                    case 53:
                    case 54:
                    case 55:
                    case 56:
                    case 57:
                    case 58:
                    case 59:
                      carry = 5;
                      product_nibble_low = product_nibble_low - 50;
                    break;
                    case 60:
                    case 61:
                    case 62:
                    case 63:
                    case 64:
                    case 65:
                    case 66:
                    case 67:
                    case 68:
                    case 69:
                      carry = 6;
                      product_nibble_low = product_nibble_low - 60;
                    break;
                    case 70:
                    case 71:
                    case 72:
                    case 73:
                    case 74:
                    case 75:
                    case 76:
                    case 77:
                    case 78:
                    case 79:
                      carry = 7;
                      product_nibble_low = product_nibble_low - 70;
                    break;         
                    case 80:
                    case 81:
                    case 82:
                    case 83:
                    case 84:
                    case 85:
                    case 86:
                    case 87:
                    case 88:
                    case 89:
                      carry = 8;
                      product_nibble_low = product_nibble_low - 80;
                    break;
                    default:
                      printf ("ERROR: encounted an invalid multiplication.\n");
                      exit(1);
                    break;
                  }
                  product_nibble_high = num1_nibble_high * num2_nibble_high + carry;
                  switch (product_nibble_high)
                  {
                    case 0:
                    case 1:
                    case 2:
                    case 3:
                    case 4:
                    case 5:
                    case 6:
                    case 7:
                    case 8:
                    case 9:
                      carry = 0;
                    break;
                    case 10:
                    case 11:
                    case 12:
                    case 13:
                    case 14:
                    case 15:
                    case 16:
                    case 17:
                    case 18:
                    case 19:
                      carry = 1;
                      product_nibble_high = product_nibble_high - 10;
                    break;
                    case 20:
                    case 21:
                    case 22:
                    case 23:
                    case 24:
                    case 25:
                    case 26:
                    case 27:
                    case 28:
                    case 29:
                      carry = 2;
                      product_nibble_high = product_nibble_high - 20;
                    break;
                    case 30:
                    case 31:
                    case 32:
                    case 33:
                    case 34:
                    case 35:
                    case 36:
                    case 37:
                    case 38:
                    case 39:
                      carry = 3;
                      product_nibble_high = product_nibble_high - 30;
                    break;
                    case 40:
                    case 41:
                    case 42:
                    case 43:
                    case 44:
                    case 45:
                    case 46:
                    case 47:
                    case 48:
                    case 49:
                      carry = 4;
                      product_nibble_high = product_nibble_high - 40;
                    break;
                    case 50:
                    case 51:
                    case 52:
                    case 53:
                    case 54:
                    case 55:
                    case 56:
                    case 57:
                    case 58:
                    case 59:
                      carry = 5;
                      product_nibble_high = product_nibble_high - 50;
                    break;
                    case 60:
                    case 61:
                    case 62:
                    case 63:
                    case 64:
                    case 65:
                    case 66:
                    case 67:
                    case 68:
                    case 69:
                      carry = 6;
                      product_nibble_high = product_nibble_high - 60;
                    break;
                    case 70:
                    case 71:
                    case 72:
                    case 73:
                    case 74:
                    case 75:
                    case 76:
                    case 77:
                    case 78:
                    case 79:
                      carry = 7;
                      product_nibble_high = product_nibble_high - 70;
                    break;         
                    case 80:
                    case 81:
                    case 82:
                    case 83:
                    case 84:
                    case 85:
                    case 86:
                    case 87:
                    case 88:
                    case 89:
                      carry = 8;
                      product_nibble_high = product_nibble_high - 80;
                    break;
                    default:
                      printf ("ERROR: encounted an invalid multiplication.\n");
      exit (EXIT_FAILURE);
                    break;
                  }
                  product_packed_byte = (product_nibble_high << 4) + product_nibble_low;
                  if (product_packed_byte > 0)
                  {
                    product_is_greater_than_zero = TRUE;
                  }
                  product = packed_string_integer_append_two_digits (product, product_packed_byte);
                }
                else
                {
                  if (temp_num1_integer_component->highest_nibble_position == lo)
                  {
                    num1_packed_byte = temp_num1_integer_component->packed_number_block[j];
                    num1_nibble_low  = num1_packed_byte & 0x0f;
// *********************************************************************
// * product_nibble_low  = num1_nibble_low  * num2_nibble_high + carry  *
// *********************************************************************
                    product_nibble_low = num1_nibble_low * num2_nibble_high + carry;
                    //printf ("num1_nibble_low = %d\n", num1_nibble_low);
                    switch (product_nibble_low)
                    {
                      case 0:
                      case 1:
                      case 2:
                      case 3:
                      case 4:
                      case 5:
                      case 6:
                      case 7:
                      case 8:
                      case 9:
                        carry = 0;
                      break;
                      case 10:
                      case 11:
                      case 12:
                      case 13:
                      case 14:
                      case 15:
                      case 16:
                      case 17:
                      case 18:
                      case 19:
                        carry = 1;
                        product_nibble_low = product_nibble_low - 10;
                      break;
                      case 20:
                      case 21:
                      case 22:
                      case 23:
                      case 24:
                      case 25:
                      case 26:
                      case 27:
                      case 28:
                      case 29:
                        carry = 2;
                        product_nibble_low = product_nibble_low - 20;
                      break;
                      case 30:
                      case 31:
                      case 32:
                      case 33:
                      case 34:
                      case 35:
                      case 36:
                      case 37:
                      case 38:
                      case 39:
                        carry = 3;
                        product_nibble_low = product_nibble_low - 30;
                      break;
                      case 40:
                      case 41:
                      case 42:
                      case 43:
                      case 44:
                      case 45:
                      case 46:
                      case 47:
                      case 48:
                      case 49:
                        carry = 4;
                        product_nibble_low = product_nibble_low - 40;
                      break;
                      case 50:
                      case 51:
                      case 52:
                      case 53:
                      case 54:
                      case 55:
                      case 56:
                      case 57:
                      case 58:
                      case 59:
                        carry = 5;
                        product_nibble_low = product_nibble_low - 50;
                      break;
                      case 60:
                      case 61:
                      case 62:
                      case 63:
                      case 64:
                      case 65:
                      case 66:
                      case 67:
                      case 68:
                      case 69:
                        carry = 6;
                        product_nibble_low = product_nibble_low - 60;
                      break;
                      case 70:
                      case 71:
                      case 72:
                      case 73:
                      case 74:
                      case 75:
                      case 76:
                      case 77:
                      case 78:
                      case 79:
                        carry = 7;
                        product_nibble_low = product_nibble_low - 70;
                      break;         
                      case 80:
                      case 81:
                      case 82:
                      case 83:
                      case 84:
                      case 85:
                      case 86:
                      case 87:
                      case 88:
                      case 89:
                        carry = 8;
                        product_nibble_low = product_nibble_low - 80;
                      break;
                      default:
                        printf ("ERROR: encounted an invalid multiplication.\n");
                        exit(1);
                      break;
                    }
                    product_packed_byte = product_nibble_low;
                    if (product_packed_byte > 0)
                    {
                      product_is_greater_than_zero = TRUE;
                    }
                    product = packed_string_integer_append_one_digit (product, product_packed_byte);
                  }
                  else
                  {
                    printf ("Internal error in _packed_string_integer_multiply(). temp_num1_integeR_component->highest_nibble_position is undefined. Exiting now.\n");
                    exit (EXIT_FAILURE);
                  }
                }
              }
              temp_num1_integer_component = temp_num1_integer_component->next_number_block;
            } 
            if (carry > 0)
            {
              product_packed_byte = carry;
              if (product_packed_byte > 0)
              {
                product_is_greater_than_zero = TRUE;
              }
              product = packed_string_integer_append_one_digit (product, product_packed_byte);
              carry = 0;
            }
            if (product_is_greater_than_zero)
            {     
              product = packed_string_integer_set_sign (product, positive);
            }
            temp_product = packed_string_integer_shift_digits_left (product, shift_left_counter); // product = temp_product * 10^i 
            if (temp_product != NULL)
            {
              greater_number = packed_string_integer_determine_absolute_value_larger_of_two_integers (temp_product, constant_one);
              if ((greater_number == 0) || (greater_number == 1)) // is temp_product greater than or equal to one? IF yes, then set sign on temp_product to positive.
              {
                temp_product = packed_string_integer_set_sign (temp_product, positive);
              }
              else
              {
                temp_product = packed_string_integer_initialize_to_zero (temp_product);
              }
            }
            else
            {
              temp_product = packed_string_integer_initialize_to_zero (temp_product);
            }
            temp_sum                = packed_string_integer_add (temp_sum, sum, temp_product);
            sum                     = packed_string_integer_release_memory (sum);
            sum                     = packed_string_integer_copy_number (sum, temp_sum);
            temp_product            = packed_string_integer_release_memory (temp_product);
            temp_sum                = packed_string_integer_release_memory (temp_sum);
            shift_left_counter++;
          } // CLOSING STATEMENT BLOCK: for (i = 0; i < temp_num2_integer_component->highest_digit_position; i++)
// ***************************************************
// * Now process num2's highest digit position digit *
// ***************************************************
          if (temp_num2_integer_component->highest_nibble_position == hi)
          {
            num2_packed_byte = temp_num2_integer_component->packed_number_block[i];
            num2_nibble_low  = num2_packed_byte & 0x0f;
            num2_nibble_high = (num2_packed_byte & 0xf0) >> 4;
            product = packed_string_integer_component_release_memory (product);
            product_is_greater_than_zero = FALSE;
            carry = 0;
            //printf ("num2_nibble_high = %d, num2_nibble_low = %d\n\n", num2_nibble_high, num2_nibble_low);
            temp_num1_integer_component = num1->left_of_decimal;
            while (temp_num1_integer_component != NULL)
            {
              if ((temp_num1_integer_component->highest_digit_position >= 0) && (temp_num1_integer_component->highest_digit_position < MAX_PACKED_NUMBER_BLOCK_SIZE))
              {
                for (j = 0; j < temp_num1_integer_component->highest_digit_position; j++)
                {
                  num1_packed_byte = temp_num1_integer_component->packed_number_block[j];
                  num1_nibble_low  = num1_packed_byte & 0x0f;
                  num1_nibble_high = (num1_packed_byte & 0xf0) >> 4;
                  product_nibble_low = num1_nibble_low * num2_nibble_low + carry;
                  //printf ("num1_nibble_high = %d, num1_nibble_low = %d\n", num1_nibble_high, num1_nibble_low);
                  switch (product_nibble_low)
                  {
                    case 0:
                    case 1:
                    case 2:
                    case 3:
                    case 4:
                    case 5:
                    case 6:
                    case 7:
                    case 8:
                    case 9:
                      carry = 0;
                    break;
                    case 10:
                    case 11:
                    case 12:
                    case 13:
                    case 14:
                    case 15:
                    case 16:
                    case 17:
                    case 18:
                    case 19:
                      carry = 1;
                      product_nibble_low = product_nibble_low - 10;
                    break;
                    case 20:
                    case 21:
                    case 22:
                    case 23:
                    case 24:
                    case 25:
                    case 26:
                    case 27:
                    case 28:
                    case 29:
                      carry = 2;
                      product_nibble_low = product_nibble_low - 20;
                    break;
                    case 30:
                    case 31:
                    case 32:
                    case 33:
                    case 34:
                    case 35:
                    case 36:
                    case 37:
                    case 38:
                    case 39:
                      carry = 3;
                      product_nibble_low = product_nibble_low - 30;
                    break;
                    case 40:
                    case 41:
                    case 42:
                    case 43:
                    case 44:
                    case 45:
                    case 46:
                    case 47:
                    case 48:
                    case 49:
                      carry = 4;
                      product_nibble_low = product_nibble_low - 40;
                    break;
                    case 50:
                    case 51:
                    case 52:
                    case 53:
                    case 54:
                    case 55:
                    case 56:
                    case 57:
                    case 58:
                    case 59:
                      carry = 5;
                      product_nibble_low = product_nibble_low - 50;
                    break;
                    case 60:
                    case 61:
                    case 62:
                    case 63:
                    case 64:
                    case 65:
                    case 66:
                    case 67:
                    case 68:
                    case 69:
                      carry = 6;
                      product_nibble_low = product_nibble_low - 60;
                    break;
                    case 70:
                    case 71:
                    case 72:
                    case 73:
                    case 74:
                    case 75:
                    case 76:
                    case 77:
                    case 78:
                    case 79:
                      carry = 7;
                      product_nibble_low = product_nibble_low - 70;
                    break;         
                    case 80:
                    case 81:
                    case 82:
                    case 83:
                    case 84:
                    case 85:
                    case 86:
                    case 87:
                    case 88:
                    case 89:
                      carry = 8;
                      product_nibble_low = product_nibble_low - 80;
                    break;
                    default:
                      printf ("ERROR: encounted an invalid multiplication. product_nibble_low = %d. num1_nibble_low = %d, num2_nibble_low = %d\n", product_nibble_low, num1_nibble_low, num2_nibble_low);
                      exit(1);
                    break;
                  }
                  product_nibble_high  = num1_nibble_high * num2_nibble_low + carry;
                  switch (product_nibble_high)
                  {
                    case 0:
                    case 1:
                    case 2:
                    case 3:
                    case 4:
                    case 5:
                    case 6:
                    case 7:
                    case 8:
                    case 9:
                      carry = 0;
                    break;
                    case 10:
                    case 11:
                    case 12:
                    case 13:
                    case 14:
                    case 15:
                    case 16:
                    case 17:
                    case 18:
                    case 19:
                      carry = 1;
                      product_nibble_high = product_nibble_high - 10;
                    break;
                    case 20:
                    case 21:
                    case 22:
                    case 23:
                    case 24:
                    case 25:
                    case 26:
                    case 27:
                    case 28:
                    case 29:
                      carry = 2;
                      product_nibble_high = product_nibble_high - 20;
                    break;
                    case 30:
                    case 31:
                    case 32:
                    case 33:
                    case 34:
                    case 35:
                    case 36:
                    case 37:
                    case 38:
                    case 39:
                      carry = 3;
                      product_nibble_high = product_nibble_high - 30;
                    break;
                    case 40:
                    case 41:
                    case 42:
                    case 43:
                    case 44:
                    case 45:
                    case 46:
                    case 47:
                    case 48:
                    case 49:
                      carry = 4;
                      product_nibble_high = product_nibble_high - 40;
                    break;
                    case 50:
                    case 51:
                    case 52:
                    case 53:
                    case 54:
                    case 55:
                    case 56:
                    case 57:
                    case 58:
                    case 59:
                      carry = 5;
                      product_nibble_high = product_nibble_high - 50;
                    break;
                    case 60:
                    case 61:
                    case 62:
                    case 63:
                    case 64:
                    case 65:
                    case 66:
                    case 67:
                    case 68:
                    case 69:
                      carry = 6;
                      product_nibble_high = product_nibble_high - 60;
                    break;
                    case 70:
                    case 71:
                    case 72:
                    case 73:
                    case 74:
                    case 75:
                    case 76:
                    case 77:
                    case 78:
                    case 79:
                      carry = 7;
                      product_nibble_high = product_nibble_high - 70;
                    break;         
                    case 80:
                    case 81:
                    case 82:
                    case 83:
                    case 84:
                    case 85:
                    case 86:
                    case 87:
                    case 88:
                    case 89:
                      carry = 8;
                      product_nibble_high = product_nibble_high - 80;
                    break;
                    default:
                      printf ("ERROR: encounted an invalid multiplication. product_nibble_high = %d, num1_nibble_high = %d, num2_nibble_high = %d, carry = %d\n", product_nibble_high, num1_nibble_high, num2_nibble_high, carry);
      exit (EXIT_FAILURE);
                    break;
                  }
                  product_packed_byte = (product_nibble_high << 4) + product_nibble_low;
                  if (product_packed_byte > 0)
                  {
                    product_is_greater_than_zero = TRUE;
                  }
                  product = packed_string_integer_append_two_digits (product, product_packed_byte);
                } // CLOSING STATEMENT BLOCK: for (j = 0; j < temp_num1_integer_component->highest_digit_position; j++)
// ***************************************************
// * Now process num1 at the highest digit position. *
// ***************************************************
                if (temp_num1_integer_component->highest_nibble_position == hi)
                {
                  num1_packed_byte = temp_num1_integer_component->packed_number_block[j];
                  num1_nibble_low  = num1_packed_byte & 0x0f;
                  num1_nibble_high = (num1_packed_byte & 0xf0) >> 4;
                  product_nibble_low = num1_nibble_low * num2_nibble_low + carry;
                  //printf ("num1_nibble_high = %d, num1_nibble_low = %d\n", num1_nibble_high, num1_nibble_low);
                  switch (product_nibble_low)
                  {
                    case 0:
                    case 1:
                    case 2:
                    case 3:
                    case 4:
                    case 5:
                    case 6:
                    case 7:
                    case 8:
                    case 9:
                      carry = 0;
                    break;
                    case 10:
                    case 11:
                    case 12:
                    case 13:
                    case 14:
                    case 15:
                    case 16:
                    case 17:
                    case 18:
                    case 19:
                      carry = 1;
                      product_nibble_low = product_nibble_low - 10;
                    break;
                    case 20:
                    case 21:
                    case 22:
                    case 23:
                    case 24:
                    case 25:
                    case 26:
                    case 27:
                    case 28:
                    case 29:
                      carry = 2;
                      product_nibble_low = product_nibble_low - 20;
                    break;
                    case 30:
                    case 31:
                    case 32:
                    case 33:
                    case 34:
                    case 35:
                    case 36:
                    case 37:
                    case 38:
                    case 39:
                      carry = 3;
                      product_nibble_low = product_nibble_low - 30;
                    break;
                    case 40:
                    case 41:
                    case 42:
                    case 43:
                    case 44:
                    case 45:
                    case 46:
                    case 47:
                    case 48:
                    case 49:
                      carry = 4;
                      product_nibble_low = product_nibble_low - 40;
                    break;
                    case 50:
                    case 51:
                    case 52:
                    case 53:
                    case 54:
                    case 55:
                    case 56:
                    case 57:
                    case 58:
                    case 59:
                      carry = 5;
                      product_nibble_low = product_nibble_low - 50;
                    break;
                    case 60:
                    case 61:
                    case 62:
                    case 63:
                    case 64:
                    case 65:
                    case 66:
                    case 67:
                    case 68:
                    case 69:
                      carry = 6;
                      product_nibble_low = product_nibble_low - 60;
                    break;
                    case 70:
                    case 71:
                    case 72:
                    case 73:
                    case 74:
                    case 75:
                    case 76:
                    case 77:
                    case 78:
                    case 79:
                      carry = 7;
                      product_nibble_low = product_nibble_low - 70;
                    break;         
                    case 80:
                    case 81:
                    case 82:
                    case 83:
                    case 84:
                    case 85:
                    case 86:
                    case 87:
                    case 88:
                    case 89:
                      carry = 8;
                      product_nibble_low = product_nibble_low - 80;
                    break;
                    default:
                      printf ("ERROR: encounted an invalid multiplication. product_nibble_low = %d. num1_nibble_low = %d, num2_nibble_low = %d\n", product_nibble_low, num1_nibble_low, num2_nibble_low);
                      exit(1);
                    break;
                  }
                  product_nibble_high = num1_nibble_high * num2_nibble_low + carry;
                  switch (product_nibble_high)
                  {
                    case 0:
                    case 1:
                    case 2:
                    case 3:
                    case 4:
                    case 5:
                    case 6:
                    case 7:
                    case 8:
                    case 9:
                      carry = 0;
                    break;
                    case 10:
                    case 11:
                    case 12:
                    case 13:
                    case 14:
                    case 15:
                    case 16:
                    case 17:
                    case 18:
                    case 19:
                      carry = 1;
                      product_nibble_high = product_nibble_high - 10;
                    break;
                    case 20:
                    case 21:
                    case 22:
                    case 23:
                    case 24:
                    case 25:
                    case 26:
                    case 27:
                    case 28:
                    case 29:
                      carry = 2;
                      product_nibble_high = product_nibble_high - 20;
                    break;
                    case 30:
                    case 31:
                    case 32:
                    case 33:
                    case 34:
                    case 35:
                    case 36:
                    case 37:
                    case 38:
                    case 39:
                      carry = 3;
                      product_nibble_high = product_nibble_high - 30;
                    break;
                    case 40:
                    case 41:
                    case 42:
                    case 43:
                    case 44:
                    case 45:
                    case 46:
                    case 47:
                    case 48:
                    case 49:
                      carry = 4;
                      product_nibble_high = product_nibble_high - 40;
                    break;
                    case 50:
                    case 51:
                    case 52:
                    case 53:
                    case 54:
                    case 55:
                    case 56:
                    case 57:
                    case 58:
                    case 59:
                      carry = 5;
                      product_nibble_high = product_nibble_high - 50;
                    break;
                    case 60:
                    case 61:
                    case 62:
                    case 63:
                    case 64:
                    case 65:
                    case 66:
                    case 67:
                    case 68:
                    case 69:
                      carry = 6;
                      product_nibble_high = product_nibble_high - 60;
                    break;
                    case 70:
                    case 71:
                    case 72:
                    case 73:
                    case 74:
                    case 75:
                    case 76:
                    case 77:
                    case 78:
                    case 79:
                      carry = 7;
                      product_nibble_high = product_nibble_high - 70;
                    break;         
                    case 80:
                    case 81:
                    case 82:
                    case 83:
                    case 84:
                    case 85:
                    case 86:
                    case 87:
                    case 88:
                    case 89:
                      carry = 8;
                      product_nibble_high = product_nibble_high - 80;
                    break;
                    default:
                      printf ("ERROR: encounted an invalid multiplication. product_nibble_high = %d, num1_nibble_high = %d, num2_nibble_high = %d, carry = %d\n", product_nibble_high, num1_nibble_high, num2_nibble_high, carry);
                      exit (EXIT_FAILURE);
                    break;
                  }
                  product_packed_byte = (product_nibble_high << 4) + product_nibble_low;
                  if (product_packed_byte > 0)
                  {
                    product_is_greater_than_zero = TRUE;
                  }
                  product = packed_string_integer_append_two_digits (product, product_packed_byte);
                }
                else
                {
                  if (temp_num1_integer_component->highest_nibble_position == lo)
                  {
                    num1_packed_byte = temp_num1_integer_component->packed_number_block[j];
                    num1_nibble_low  = num1_packed_byte & 0x0f;
// *********************************************************************
// * product_nibble_low  = num1_nibble_low  * num2_nibble_low + carry  *
// *********************************************************************
                    product_nibble_low = num1_nibble_low * num2_nibble_low + carry;
                    switch (product_nibble_low)
                    {
                      case 0:
                      case 1:
                      case 2:
                      case 3:
                      case 4:
                      case 5:
                      case 6:
                      case 7:
                      case 8:
                      case 9:
                        carry = 0;
                      break;
                      case 10:
                      case 11:
                      case 12:
                      case 13:
                      case 14:
                      case 15:
                      case 16:
                      case 17:
                      case 18:
                      case 19:
                        carry = 1;
                        product_nibble_low = product_nibble_low - 10;
                      break;
                      case 20:
                      case 21:
                      case 22:
                      case 23:
                      case 24:
                      case 25:
                      case 26:
                      case 27:
                      case 28:
                      case 29:
                        carry = 2;
                        product_nibble_low = product_nibble_low - 20;
                      break;
                      case 30:
                      case 31:
                      case 32:
                      case 33:
                      case 34:
                      case 35:
                      case 36:
                      case 37:
                      case 38:
                      case 39:
                        carry = 3;
                        product_nibble_low = product_nibble_low - 30;
                      break;
                      case 40:
                      case 41:
                      case 42:
                      case 43:
                      case 44:
                      case 45:
                      case 46:
                      case 47:
                      case 48:
                      case 49:
                        carry = 4;
                        product_nibble_low = product_nibble_low - 40;
                      break;
                      case 50:
                      case 51:
                      case 52:
                      case 53:
                      case 54:
                      case 55:
                      case 56:
                      case 57:
                      case 58:
                      case 59:
                        carry = 5;
                        product_nibble_low = product_nibble_low - 50;
                      break;
                      case 60:
                      case 61:
                      case 62:
                      case 63:
                      case 64:
                      case 65:
                      case 66:
                      case 67:
                      case 68:
                      case 69:
                        carry = 6;
                        product_nibble_low = product_nibble_low - 60;
                      break;
                      case 70:
                      case 71:
                      case 72:
                      case 73:
                      case 74:
                      case 75:
                      case 76:
                      case 77:
                      case 78:
                      case 79:
                        carry = 7;
                        product_nibble_low = product_nibble_low - 70;
                      break;         
                      case 80:
                      case 81:
                      case 82:
                      case 83:
                      case 84:
                      case 85:
                      case 86:
                      case 87:
                      case 88:
                      case 89:
                        carry = 8;
                        product_nibble_low = product_nibble_low - 80;
                      break;
                      default:
                        printf ("ERROR: encounted an invalid multiplication. product_nibble_low = %d. num1_nibble_low = %d, num2_nibble_low = %d\n", product_nibble_low, num1_nibble_low, num2_nibble_low);
                        exit(1);
                      break;
                    }
                    product_packed_byte = product_nibble_low;
                    if (product_packed_byte > 0)
                    {
                      product_is_greater_than_zero = TRUE;
                    }
                    product = packed_string_integer_append_one_digit (product, product_packed_byte);
                  }
                  else
                  {
                    printf ("Internal error in _packed_string_integer_multiply(). temp_num1_integeR_component->highest_nibble_position is undefined. Exiting now.\n");
                    exit (EXIT_FAILURE);
                  }
                }
              }
              temp_num1_integer_component = temp_num1_integer_component->next_number_block;
            } 
            if (carry > 0)
            {
              product_packed_byte = carry;
              if (product_packed_byte > 0)
              {
                product_is_greater_than_zero = TRUE;
              }
              product = packed_string_integer_append_one_digit (product, product_packed_byte);
              carry = 0;
            }
            if (product_is_greater_than_zero)
            {     
              product = packed_string_integer_set_sign (product, positive);
            }
            temp_product = packed_string_integer_shift_digits_left (product, shift_left_counter); // product = temp_product * 10^i 
            if (temp_product != NULL)
            {
              greater_number = packed_string_integer_determine_absolute_value_larger_of_two_integers (temp_product, constant_one);
              if ((greater_number == 0) || (greater_number == 1)) // is temp_product greater than or equal to one? IF yes, then set sign on temp_product to positive.
              {
                temp_product = packed_string_integer_set_sign (temp_product, positive);
              }
              else
              {
                temp_product = packed_string_integer_initialize_to_zero (temp_product);
              }
            }
            else
            {
              temp_product = packed_string_integer_initialize_to_zero (temp_product);
            }
            temp_sum                = packed_string_integer_add (temp_sum, sum, temp_product);
            sum                     = packed_string_integer_component_release_memory (sum);
            sum                     = packed_string_integer_copy_number (sum, temp_sum);
            temp_product            = packed_string_integer_release_memory (temp_product);
            temp_sum                = packed_string_integer_release_memory (temp_sum);
            shift_left_counter++;
// ***********************************
// * Now process num2's high nibble. *
// ***********************************
            product = packed_string_integer_component_release_memory (product);
            product_is_greater_than_zero = FALSE;
            carry = 0;
            temp_num1_integer_component = num1->left_of_decimal;
            while (temp_num1_integer_component != NULL)
            {
              if ((temp_num1_integer_component->highest_digit_position >= 0) && (temp_num1_integer_component->highest_digit_position < MAX_PACKED_NUMBER_BLOCK_SIZE))
              {
                for (j = 0; j < temp_num1_integer_component->highest_digit_position; j++)
                {
                  num1_packed_byte = temp_num1_integer_component->packed_number_block[j];
                  num1_nibble_low  = num1_packed_byte & 0x0f;
                  num1_nibble_high = (num1_packed_byte & 0xf0) >> 4;
                  product_nibble_low = num1_nibble_low * num2_nibble_high + carry;
                  //printf ("num1_nibble_high = %d, num1_nibble_low = %d\n", num1_nibble_high, num1_nibble_low);
                  switch (product_nibble_low)
                  {
                    case 0:
                    case 1:
                    case 2:
                    case 3:
                    case 4:
                    case 5:
                    case 6:
                    case 7:
                    case 8:
                    case 9:
                      carry = 0;
                    break;
                    case 10:
                    case 11:
                    case 12:
                    case 13:
                    case 14:
                    case 15:
                    case 16:
                    case 17:
                    case 18:
                    case 19:
                      carry = 1;
                      product_nibble_low = product_nibble_low - 10;
                    break;
                    case 20:
                    case 21:
                    case 22:
                    case 23:
                    case 24:
                    case 25:
                    case 26:
                    case 27:
                    case 28:
                    case 29:
                      carry = 2;
                      product_nibble_low = product_nibble_low - 20;
                    break;
                    case 30:
                    case 31:
                    case 32:
                    case 33:
                    case 34:
                    case 35:
                    case 36:
                    case 37:
                    case 38:
                    case 39:
                      carry = 3;
                      product_nibble_low = product_nibble_low - 30;
                    break;
                    case 40:
                    case 41:
                    case 42:
                    case 43:
                    case 44:
                    case 45:
                    case 46:
                    case 47:
                    case 48:
                    case 49:
                      carry = 4;
                      product_nibble_low = product_nibble_low - 40;
                    break;
                    case 50:
                    case 51:
                    case 52:
                    case 53:
                    case 54:
                    case 55:
                    case 56:
                    case 57:
                    case 58:
                    case 59:
                      carry = 5;
                      product_nibble_low = product_nibble_low - 50;
                    break;
                    case 60:
                    case 61:
                    case 62:
                    case 63:
                    case 64:
                    case 65:
                    case 66:
                    case 67:
                    case 68:
                    case 69:
                      carry = 6;
                      product_nibble_low = product_nibble_low - 60;
                    break;
                    case 70:
                    case 71:
                    case 72:
                    case 73:
                    case 74:
                    case 75:
                    case 76:
                    case 77:
                    case 78:
                    case 79:
                      carry = 7;
                      product_nibble_low = product_nibble_low - 70;
                    break;         
                    case 80:
                    case 81:
                    case 82:
                    case 83:
                    case 84:
                    case 85:
                    case 86:
                    case 87:
                    case 88:
                    case 89:
                      carry = 8;
                      product_nibble_low = product_nibble_low - 80;
                    break;
                    default:
                      printf ("ERROR: encounted an invalid multiplication.\n");
                      exit(1);
                    break;
                  }
                  product_nibble_high  = num1_nibble_high * num2_nibble_high + carry;
                  switch (product_nibble_high)
                  {
                    case 0:
                    case 1:
                    case 2:
                    case 3:
                    case 4:
                    case 5:
                    case 6:
                    case 7:
                    case 8:
                    case 9:
                      carry = 0;
                    break;
                    case 10:
                    case 11:
                    case 12:
                    case 13:
                    case 14:
                    case 15:
                    case 16:
                    case 17:
                    case 18:
                    case 19:
                      carry = 1;
                      product_nibble_high = product_nibble_high - 10;
                    break;
                    case 20:
                    case 21:
                    case 22:
                    case 23:
                    case 24:
                    case 25:
                    case 26:
                    case 27:
                    case 28:
                    case 29:
                      carry = 2;
                      product_nibble_high = product_nibble_high - 20;
                    break;
                    case 30:
                    case 31:
                    case 32:
                    case 33:
                    case 34:
                    case 35:
                    case 36:
                    case 37:
                    case 38:
                    case 39:
                      carry = 3;
                      product_nibble_high = product_nibble_high - 30;
                    break;
                    case 40:
                    case 41:
                    case 42:
                    case 43:
                    case 44:
                    case 45:
                    case 46:
                    case 47:
                    case 48:
                    case 49:
                      carry = 4;
                      product_nibble_high = product_nibble_high - 40;
                    break;
                    case 50:
                    case 51:
                    case 52:
                    case 53:
                    case 54:
                    case 55:
                    case 56:
                    case 57:
                    case 58:
                    case 59:
                      carry = 5;
                      product_nibble_high = product_nibble_high - 50;
                    break;
                    case 60:
                    case 61:
                    case 62:
                    case 63:
                    case 64:
                    case 65:
                    case 66:
                    case 67:
                    case 68:
                    case 69:
                      carry = 6;
                      product_nibble_high = product_nibble_high - 60;
                    break;
                    case 70:
                    case 71:
                    case 72:
                    case 73:
                    case 74:
                    case 75:
                    case 76:
                    case 77:
                    case 78:
                    case 79:
                      carry = 7;
                      product_nibble_high = product_nibble_high - 70;
                    break;         
                    case 80:
                    case 81:
                    case 82:
                    case 83:
                    case 84:
                    case 85:
                    case 86:
                    case 87:
                    case 88:
                    case 89:
                      carry = 8;
                      product_nibble_high = product_nibble_high - 80;
                    break;
                    default:
                      printf ("ERROR: encounted an invalid multiplication.\n");
                      exit (EXIT_FAILURE);
                    break;
                  }
                  product_packed_byte = (product_nibble_high << 4) + product_nibble_low;
                  if (product_packed_byte > 0)
                  {
                    product_is_greater_than_zero = TRUE;
                  }
                  product = packed_string_integer_append_two_digits (product, product_packed_byte);
                } // CLOSING STATEMENT BLOCK: for (j = 0; j < temp_num1_integer_component->highest_digit_position; j++)
// ***************************************************
// * Now process num1 at the highest digit position. *
// ***************************************************
                if (temp_num1_integer_component->highest_nibble_position == hi)
                {
                  num1_packed_byte = temp_num1_integer_component->packed_number_block[j];
                  num1_nibble_low  = num1_packed_byte & 0x0f;
                  num1_nibble_high = (num1_packed_byte & 0xf0) >> 4;
                  product_nibble_low = num1_nibble_low * num2_nibble_high + carry;
                  //printf ("num1_nibble_high = %d, num1_nibble_low = %d\n", num1_nibble_high, num1_nibble_low);
                  switch (product_nibble_low)
                  {
                    case 0:
                    case 1:
                    case 2:
                    case 3:
                    case 4:
                    case 5:
                    case 6:
                    case 7:
                    case 8:
                    case 9:
                      carry = 0;
                    break;
                    case 10:
                    case 11:
                    case 12:
                    case 13:
                    case 14:
                    case 15:
                    case 16:
                    case 17:
                    case 18:
                    case 19:
                      carry = 1;
                      product_nibble_low = product_nibble_low - 10;
                    break;
                    case 20:
                    case 21:
                    case 22:
                    case 23:
                    case 24:
                    case 25:
                    case 26:
                    case 27:
                    case 28:
                    case 29:
                      carry = 2;
                      product_nibble_low = product_nibble_low - 20;
                    break;
                    case 30:
                    case 31:
                    case 32:
                    case 33:
                    case 34:
                    case 35:
                    case 36:
                    case 37:
                    case 38:
                    case 39:
                      carry = 3;
                      product_nibble_low = product_nibble_low - 30;
                    break;
                    case 40:
                    case 41:
                    case 42:
                    case 43:
                    case 44:
                    case 45:
                    case 46:
                    case 47:
                    case 48:
                    case 49:
                      carry = 4;
                      product_nibble_low = product_nibble_low - 40;
                    break;
                    case 50:
                    case 51:
                    case 52:
                    case 53:
                    case 54:
                    case 55:
                    case 56:
                    case 57:
                    case 58:
                    case 59:
                      carry = 5;
                      product_nibble_low = product_nibble_low - 50;
                    break;
                    case 60:
                    case 61:
                    case 62:
                    case 63:
                    case 64:
                    case 65:
                    case 66:
                    case 67:
                    case 68:
                    case 69:
                      carry = 6;
                      product_nibble_low = product_nibble_low - 60;
                    break;
                    case 70:
                    case 71:
                    case 72:
                    case 73:
                    case 74:
                    case 75:
                    case 76:
                    case 77:
                    case 78:
                    case 79:
                      carry = 7;
                      product_nibble_low = product_nibble_low - 70;
                    break;         
                    case 80:
                    case 81:
                    case 82:
                    case 83:
                    case 84:
                    case 85:
                    case 86:
                    case 87:
                    case 88:
                    case 89:
                      carry = 8;
                      product_nibble_low = product_nibble_low - 80;
                    break;
                    default:
                      printf ("ERROR: encounted an invalid multiplication.\n");
                      exit(1);
                    break;
                  }
                  product_nibble_high = num1_nibble_high * num2_nibble_high + carry;
                  switch (product_nibble_high)
                  {
                    case 0:
                    case 1:
                    case 2:
                    case 3:
                    case 4:
                    case 5:
                    case 6:
                    case 7:
                    case 8:
                    case 9:
                      carry = 0;
                    break;
                    case 10:
                    case 11:
                    case 12:
                    case 13:
                    case 14:
                    case 15:
                    case 16:
                    case 17:
                    case 18:
                    case 19:
                      carry = 1;
                      product_nibble_high = product_nibble_high - 10;
                    break;
                    case 20:
                    case 21:
                    case 22:
                    case 23:
                    case 24:
                    case 25:
                    case 26:
                    case 27:
                    case 28:
                    case 29:
                      carry = 2;
                      product_nibble_high = product_nibble_high - 20;
                    break;
                    case 30:
                    case 31:
                    case 32:
                    case 33:
                    case 34:
                    case 35:
                    case 36:
                    case 37:
                    case 38:
                    case 39:
                      carry = 3;
                      product_nibble_high = product_nibble_high - 30;
                    break;
                    case 40:
                    case 41:
                    case 42:
                    case 43:
                    case 44:
                    case 45:
                    case 46:
                    case 47:
                    case 48:
                    case 49:
                      carry = 4;
                      product_nibble_high = product_nibble_high - 40;
                    break;
                    case 50:
                    case 51:
                    case 52:
                    case 53:
                    case 54:
                    case 55:
                    case 56:
                    case 57:
                    case 58:
                    case 59:
                      carry = 5;
                      product_nibble_high = product_nibble_high - 50;
                    break;
                    case 60:
                    case 61:
                    case 62:
                    case 63:
                    case 64:
                    case 65:
                    case 66:
                    case 67:
                    case 68:
                    case 69:
                      carry = 6;
                      product_nibble_high = product_nibble_high - 60;
                    break;
                    case 70:
                    case 71:
                    case 72:
                    case 73:
                    case 74:
                    case 75:
                    case 76:
                    case 77:
                    case 78:
                    case 79:
                      carry = 7;
                      product_nibble_high = product_nibble_high - 70;
                    break;         
                    case 80:
                    case 81:
                    case 82:
                    case 83:
                    case 84:
                    case 85:
                    case 86:
                    case 87:
                    case 88:
                    case 89:
                      carry = 8;
                      product_nibble_high = product_nibble_high - 80;
                    break;
                    default:
                      printf ("ERROR: encounted an invalid multiplication.\n");
                      exit (EXIT_FAILURE);
                    break;
                  }
                  product_packed_byte = (product_nibble_high << 4) + product_nibble_low;
                  if (product_packed_byte > 0)
                  {
                    product_is_greater_than_zero = TRUE;
                  }
                  product = packed_string_integer_append_two_digits (product, product_packed_byte);
                }
                else
                {
                  if (temp_num1_integer_component->highest_nibble_position == lo)
                  {
                    num1_packed_byte = temp_num1_integer_component->packed_number_block[j];
                    num1_nibble_low  = num1_packed_byte & 0x0f;
// *********************************************************************
// * product_nibble_low  = num1_nibble_low  * num2_nibble_high + carry  *
// *********************************************************************
                    product_nibble_low = num1_nibble_low * num2_nibble_high + carry;
                    //printf ("num1_nibble_low = %d\n", num1_nibble_low);
                    switch (product_nibble_low)
                    {
                      case 0:
                      case 1:
                      case 2:
                      case 3:
                      case 4:
                      case 5:
                      case 6:
                      case 7:
                      case 8:
                      case 9:
                        carry = 0;
                      break;
                      case 10:
                      case 11:
                      case 12:
                      case 13:
                      case 14:
                      case 15:
                      case 16:
                      case 17:
                      case 18:
                      case 19:
                        carry = 1;
                        product_nibble_low = product_nibble_low - 10;
                      break;
                      case 20:
                      case 21:
                      case 22:
                      case 23:
                      case 24:
                      case 25:
                      case 26:
                      case 27:
                      case 28:
                      case 29:
                        carry = 2;
                        product_nibble_low = product_nibble_low - 20;
                      break;
                      case 30:
                      case 31:
                      case 32:
                      case 33:
                      case 34:
                      case 35:
                      case 36:
                      case 37:
                      case 38:
                      case 39:
                        carry = 3;
                        product_nibble_low = product_nibble_low - 30;
                      break;
                      case 40:
                      case 41:
                      case 42:
                      case 43:
                      case 44:
                      case 45:
                      case 46:
                      case 47:
                      case 48:
                      case 49:
                        carry = 4;
                        product_nibble_low = product_nibble_low - 40;
                      break;
                      case 50:
                      case 51:
                      case 52:
                      case 53:
                      case 54:
                      case 55:
                      case 56:
                      case 57:
                      case 58:
                      case 59:
                        carry = 5;
                        product_nibble_low = product_nibble_low - 50;
                      break;
                      case 60:
                      case 61:
                      case 62:
                      case 63:
                      case 64:
                      case 65:
                      case 66:
                      case 67:
                      case 68:
                      case 69:
                        carry = 6;
                        product_nibble_low = product_nibble_low - 60;
                      break;
                      case 70:
                      case 71:
                      case 72:
                      case 73:
                      case 74:
                      case 75:
                      case 76:
                      case 77:
                      case 78:
                      case 79:
                        carry = 7;
                        product_nibble_low = product_nibble_low - 70;
                      break;         
                      case 80:
                      case 81:
                      case 82:
                      case 83:
                      case 84:
                      case 85:
                      case 86:
                      case 87:
                      case 88:
                      case 89:
                        carry = 8;
                        product_nibble_low = product_nibble_low - 80;
                      break;
                      default:
                        printf ("ERROR: encounted an invalid multiplication.\n");
                        exit(1);
                      break;
                    }
                    product_packed_byte = product_nibble_low;
                    if (product_packed_byte > 0)
                    {
                      product_is_greater_than_zero = TRUE;
                    }
                    product = packed_string_integer_append_one_digit (product, product_packed_byte);
                  }
                  else
                  {
                    printf ("Internal error in _packed_string_integer_multiply(). temp_num1_integeR_component->highest_nibble_position is undefined. Exiting now.\n");
                    exit (EXIT_FAILURE);
                  }
                }
              }
              temp_num1_integer_component = temp_num1_integer_component->next_number_block;
            } 
            if (carry > 0)
            {
              product_packed_byte = carry;
              if (product_packed_byte > 0)
              {
                product_is_greater_than_zero = TRUE;
              }
              product = packed_string_integer_append_one_digit (product, product_packed_byte);
              carry = 0;
            }
            if (product_is_greater_than_zero)
            {     
              product = packed_string_integer_set_sign (product, positive);
            }
            temp_product = packed_string_integer_shift_digits_left (product, shift_left_counter); // product = temp_product * 10^i 
            greater_number = packed_string_integer_determine_absolute_value_larger_of_two_integers (temp_product, constant_one);
            if ((greater_number == 0) || (greater_number == 1)) // is temp_product greater than or equal to one? IF yes, then set sign on temp_product to positive.
            {
              temp_product = packed_string_integer_set_sign (temp_product, positive);
            }
            temp_sum                = packed_string_integer_add (temp_sum, sum, temp_product);
            sum                     = packed_string_integer_component_release_memory (sum);
            sum                     = packed_string_integer_copy_number (sum, temp_sum);
            temp_product            = packed_string_integer_release_memory (temp_product);
            temp_sum                = packed_string_integer_release_memory (temp_sum);
            shift_left_counter++;
          }
          else
          {
            if (temp_num2_integer_component->highest_nibble_position == lo)
            {
              num2_packed_byte = temp_num2_integer_component->packed_number_block[i];
              num2_nibble_low  = num2_packed_byte & 0x0f;
              product = packed_string_integer_release_memory (product);
              product_is_greater_than_zero = FALSE;
              carry = 0;
              //printf ("num2_nibble_low = %d\n\n", num2_nibble_low);
              temp_num1_integer_component = num1->left_of_decimal;
              while (temp_num1_integer_component != NULL)
              {
                if ((temp_num1_integer_component->highest_digit_position >= 0) && (temp_num1_integer_component->highest_digit_position < MAX_PACKED_NUMBER_BLOCK_SIZE))
                {
                  for (j = 0; j < temp_num1_integer_component->highest_digit_position; j++)
                  {
                    num1_packed_byte = temp_num1_integer_component->packed_number_block[j];
                    num1_nibble_low  = num1_packed_byte & 0x0f;
                    num1_nibble_high = (num1_packed_byte & 0xf0) >> 4;
                    product_nibble_low = num1_nibble_low * num2_nibble_low + carry;
                    //printf ("num1_nibble_high = %d, num1_nibble_low = %d\n", num1_nibble_high, num1_nibble_low);
                    switch (product_nibble_low)
                    {
                      case 0:
                      case 1:
                      case 2:
                      case 3:
                      case 4:
                      case 5:
                      case 6:
                      case 7:
                      case 8:
                      case 9:
                        carry = 0;
                      break;
                      case 10:
                      case 11:
                      case 12:
                      case 13:
                      case 14:
                      case 15:
                      case 16:
                      case 17:
                      case 18:
                      case 19:
                        carry = 1;
                        product_nibble_low = product_nibble_low - 10;
                      break;
                      case 20:
                      case 21:
                      case 22:
                      case 23:
                      case 24:
                      case 25:
                      case 26:
                      case 27:
                      case 28:
                      case 29:
                        carry = 2;
                        product_nibble_low = product_nibble_low - 20;
                      break;
                      case 30:
                      case 31:
                      case 32:
                      case 33:
                      case 34:
                      case 35:
                      case 36:
                      case 37:
                      case 38:
                      case 39:
                        carry = 3;
                        product_nibble_low = product_nibble_low - 30;
                      break;
                      case 40:
                      case 41:
                      case 42:
                      case 43:
                      case 44:
                      case 45:
                      case 46:
                      case 47:
                      case 48:
                      case 49:
                        carry = 4;
                        product_nibble_low = product_nibble_low - 40;
                      break;
                      case 50:
                      case 51:
                      case 52:
                      case 53:
                      case 54:
                      case 55:
                      case 56:
                      case 57:
                      case 58:
                      case 59:
                        carry = 5;
                        product_nibble_low = product_nibble_low - 50;
                      break;
                      case 60:
                      case 61:
                      case 62:
                      case 63:
                      case 64:
                      case 65:
                      case 66:
                      case 67:
                      case 68:
                      case 69:
                        carry = 6;
                        product_nibble_low = product_nibble_low - 60;
                      break;
                      case 70:
                      case 71:
                      case 72:
                      case 73:
                      case 74:
                      case 75:
                      case 76:
                      case 77:
                      case 78:
                      case 79:
                        carry = 7;
                        product_nibble_low = product_nibble_low - 70;
                      break;         
                      case 80:
                      case 81:
                      case 82:
                      case 83:
                      case 84:
                      case 85:
                      case 86:
                      case 87:
                      case 88:
                      case 89:
                        carry = 8;
                        product_nibble_low = product_nibble_low - 80;
                      break;
                      default:
                        printf ("ERROR: encounted an invalid multiplication. product_nibble_low = %d. num1_nibble_low = %d, num2_nibble_low = %d\n", product_nibble_low, num1_nibble_low, num2_nibble_low);
                        exit(1);
                      break;
                    }
                    product_nibble_high  = num1_nibble_high * num2_nibble_low + carry;
                    switch (product_nibble_high)
                    {
                      case 0:
                      case 1:
                      case 2:
                      case 3:
                      case 4:
                      case 5:
                      case 6:
                      case 7:
                      case 8:
                      case 9:
                        carry = 0;
                      break;
                      case 10:
                      case 11:
                      case 12:
                      case 13:
                      case 14:
                      case 15:
                      case 16:
                      case 17:
                      case 18:
                      case 19:
                        carry = 1;
                        product_nibble_high = product_nibble_high - 10;
                      break;
                      case 20:
                      case 21:
                      case 22:
                      case 23:
                      case 24:
                      case 25:
                      case 26:
                      case 27:
                      case 28:
                      case 29:
                        carry = 2;
                        product_nibble_high = product_nibble_high - 20;
                      break;
                      case 30:
                      case 31:
                      case 32:
                      case 33:
                      case 34:
                      case 35:
                      case 36:
                      case 37:
                      case 38:
                      case 39:
                        carry = 3;
                        product_nibble_high = product_nibble_high - 30;
                      break;
                      case 40:
                      case 41:
                      case 42:
                      case 43:
                      case 44:
                      case 45:
                      case 46:
                      case 47:
                      case 48:
                      case 49:
                        carry = 4;
                        product_nibble_high = product_nibble_high - 40;
                      break;
                      case 50:
                      case 51:
                      case 52:
                      case 53:
                      case 54:
                      case 55:
                      case 56:
                      case 57:
                      case 58:
                      case 59:
                        carry = 5;
                        product_nibble_high = product_nibble_high - 50;
                      break;
                      case 60:
                      case 61:
                      case 62:
                      case 63:
                      case 64:
                      case 65:
                      case 66:
                      case 67:
                      case 68:
                      case 69:
                        carry = 6;
                        product_nibble_high = product_nibble_high - 60;
                      break;
                      case 70:
                      case 71:
                      case 72:
                      case 73:
                      case 74:
                      case 75:
                      case 76:
                      case 77:
                      case 78:
                      case 79:
                        carry = 7;
                        product_nibble_high = product_nibble_high - 70;
                      break;         
                      case 80:
                      case 81:
                      case 82:
                      case 83:
                      case 84:
                      case 85:
                      case 86:
                      case 87:
                      case 88:
                      case 89:
                        carry = 8;
                        product_nibble_high = product_nibble_high - 80;
                      break;
                      default:
                        printf ("Error in _packed_string_integer_multiply: encountered invalid digit. Exiting now.\n");
                        exit (EXIT_FAILURE);
                      break;
                    }
                    product_packed_byte = (product_nibble_high << 4) + product_nibble_low;
                    if (product_packed_byte > 0)
                    {
                      product_is_greater_than_zero = TRUE;
                    }
                    product = packed_string_integer_append_two_digits (product, product_packed_byte);
                  } // CLOSING STATEMENT BLOCK: for (j = 0; j < temp_num1_integer_component->highest_digit_position; j++)
// *************************************************
// Now process num1 at the highest digit position. *
// *************************************************
                  if (temp_num1_integer_component->highest_nibble_position == hi)
                  {
                    num1_packed_byte = temp_num1_integer_component->packed_number_block[j];
                    num1_nibble_low  = num1_packed_byte & 0x0f;
                    num1_nibble_high = (num1_packed_byte & 0xf0) >> 4;
                    product_nibble_low = num1_nibble_low * num2_nibble_low + carry;
                    //printf ("num1_nibble_high = %d, num1_nibble_low = %d\n", num1_nibble_high, num1_nibble_low);
                    switch (product_nibble_low)
                    {
                      case 0:
                      case 1:
                      case 2:
                      case 3:
                      case 4:
                      case 5:
                      case 6:
                      case 7:
                      case 8:
                      case 9:
                        carry = 0;
                      break;
                      case 10:
                      case 11:
                      case 12:
                      case 13:
                      case 14:
                      case 15:
                      case 16:
                      case 17:
                      case 18:
                      case 19:
                        carry = 1;
                        product_nibble_low = product_nibble_low - 10;
                      break;
                      case 20:
                      case 21:
                      case 22:
                      case 23:
                      case 24:
                      case 25:
                      case 26:
                      case 27:
                      case 28:
                      case 29:
                        carry = 2;
                        product_nibble_low = product_nibble_low - 20;
                      break;
                      case 30:
                      case 31:
                      case 32:
                      case 33:
                      case 34:
                      case 35:
                      case 36:
                      case 37:
                      case 38:
                      case 39:
                        carry = 3;
                        product_nibble_low = product_nibble_low - 30;
                      break;
                      case 40:
                      case 41:
                      case 42:
                      case 43:
                      case 44:
                      case 45:
                      case 46:
                      case 47:
                      case 48:
                      case 49:
                        carry = 4;
                        product_nibble_low = product_nibble_low - 40;
                      break;
                      case 50:
                      case 51:
                      case 52:
                      case 53:
                      case 54:
                      case 55:
                      case 56:
                      case 57:
                      case 58:
                      case 59:
                        carry = 5;
                        product_nibble_low = product_nibble_low - 50;
                      break;
                      case 60:
                      case 61:
                      case 62:
                      case 63:
                      case 64:
                      case 65:
                      case 66:
                      case 67:
                      case 68:
                      case 69:
                        carry = 6;
                        product_nibble_low = product_nibble_low - 60;
                      break;
                      case 70:
                      case 71:
                      case 72:
                      case 73:
                      case 74:
                      case 75:
                      case 76:
                      case 77:
                      case 78:
                      case 79:
                        carry = 7;
                        product_nibble_low = product_nibble_low - 70;
                      break;         
                      case 80:
                      case 81:
                      case 82:
                      case 83:
                      case 84:
                      case 85:
                      case 86:
                      case 87:
                      case 88:
                      case 89:
                        carry = 8;
                        product_nibble_low = product_nibble_low - 80;
                      break;
                      default:
                        printf ("Error in _packed_string_integer_multiply: encountered invalid digit. Exiting now.\n");
                        exit (EXIT_FAILURE);
                      break;
                    }
                    product_nibble_high = num1_nibble_high * num2_nibble_low + carry;
                    switch (product_nibble_high)
                    {
                      case 0:
                      case 1:
                      case 2:
                      case 3:
                      case 4:
                      case 5:
                      case 6:
                      case 7:
                      case 8:
                      case 9:
                        carry = 0;
                      break;
                      case 10:
                      case 11:
                      case 12:
                      case 13:
                      case 14:
                      case 15:
                      case 16:
                      case 17:
                      case 18:
                      case 19:
                        carry = 1;
                        product_nibble_high = product_nibble_high - 10;
                      break;
                      case 20:
                      case 21:
                      case 22:
                      case 23:
                      case 24:
                      case 25:
                      case 26:
                      case 27:
                      case 28:
                      case 29:
                        carry = 2;
                        product_nibble_high = product_nibble_high - 20;
                      break;
                      case 30:
                      case 31:
                      case 32:
                      case 33:
                      case 34:
                      case 35:
                      case 36:
                      case 37:
                      case 38:
                      case 39:
                        carry = 3;
                        product_nibble_high = product_nibble_high - 30;
                      break;
                      case 40:
                      case 41:
                      case 42:
                      case 43:
                      case 44:
                      case 45:
                      case 46:
                      case 47:
                      case 48:
                      case 49:
                        carry = 4;
                        product_nibble_high = product_nibble_high - 40;
                      break;
                      case 50:
                      case 51:
                      case 52:
                      case 53:
                      case 54:
                      case 55:
                      case 56:
                      case 57:
                      case 58:
                      case 59:
                        carry = 5;
                        product_nibble_high = product_nibble_high - 50;
                      break;
                      case 60:
                      case 61:
                      case 62:
                      case 63:
                      case 64:
                      case 65:
                      case 66:
                      case 67:
                      case 68:
                      case 69:
                        carry = 6;
                        product_nibble_high = product_nibble_high - 60;
                      break;
                      case 70:
                      case 71:
                      case 72:
                      case 73:
                      case 74:
                      case 75:
                      case 76:
                      case 77:
                      case 78:
                      case 79:
                        carry = 7;
                        product_nibble_high = product_nibble_high - 70;
                      break;         
                      case 80:
                      case 81:
                      case 82:
                      case 83:
                      case 84:
                      case 85:
                      case 86:
                      case 87:
                      case 88:
                      case 89:
                        carry = 8;
                        product_nibble_high = product_nibble_high - 80;
                      break;
                      default:
                        printf ("Error in _packed_string_integer_multiply: encountered an invalid digit. Exiting now.\n");
                        exit (EXIT_FAILURE);
                      break;
                    }
                    product_packed_byte = (product_nibble_high << 4) + product_nibble_low;
                    if (product_packed_byte > 0)
                    {
                      product_is_greater_than_zero = TRUE;
                    }
                    product = packed_string_integer_append_two_digits (product, product_packed_byte);
                  }
                  else
                  {
                    if (temp_num1_integer_component->highest_nibble_position == lo)
                    {
                      num1_packed_byte = temp_num1_integer_component->packed_number_block[j];
                      num1_nibble_low  = num1_packed_byte & 0x0f;
// *********************************************************************
// * product_nibble_low  = num1_nibble_low  * num2_nibble_low + carry  *
// *********************************************************************
                      product_nibble_low = num1_nibble_low * num2_nibble_low + carry;
                      //printf ("num1_nibble_low = %d\n", num1_nibble_low);
                      switch (product_nibble_low)
                      {
                        case 0:
                        case 1:
                        case 2:
                        case 3:
                        case 4:
                        case 5:
                        case 6:
                        case 7:
                        case 8:
                        case 9:
                          carry = 0;
                        break;
                        case 10:
                        case 11:
                        case 12:
                        case 13:
                        case 14:
                        case 15:
                        case 16:
                        case 17:
                        case 18:
                        case 19:
                          carry = 1;
                          product_nibble_low = product_nibble_low - 10;
                        break;
                        case 20:
                        case 21:
                        case 22:
                        case 23:
                        case 24:
                        case 25:
                        case 26:
                        case 27:
                        case 28:
                        case 29:
                          carry = 2;
                          product_nibble_low = product_nibble_low - 20;
                        break;
                        case 30:
                        case 31:
                        case 32:
                        case 33:
                        case 34:
                        case 35:
                        case 36:
                        case 37:
                        case 38:
                        case 39:
                          carry = 3;
                          product_nibble_low = product_nibble_low - 30;
                        break;
                        case 40:
                        case 41:
                        case 42:
                        case 43:
                        case 44:
                        case 45:
                        case 46:
                        case 47:
                        case 48:
                        case 49:
                          carry = 4;
                          product_nibble_low = product_nibble_low - 40;
                        break;
                        case 50:
                        case 51:
                        case 52:
                        case 53:
                        case 54:
                        case 55:
                        case 56:
                        case 57:
                        case 58:
                        case 59:
                          carry = 5;
                          product_nibble_low = product_nibble_low - 50;
                        break;
                        case 60:
                        case 61:
                        case 62:
                        case 63:
                        case 64:
                        case 65:
                        case 66:
                        case 67:
                        case 68:
                        case 69:
                          carry = 6;
                          product_nibble_low = product_nibble_low - 60;
                        break;
                        case 70:
                        case 71:
                        case 72:
                        case 73:
                        case 74:
                        case 75:
                        case 76:
                        case 77:
                        case 78:
                        case 79:
                          carry = 7;
                          product_nibble_low = product_nibble_low - 70;
                        break;         
                        case 80:
                        case 81:
                        case 82:
                        case 83:
                        case 84:
                        case 85:
                        case 86:
                        case 87:
                        case 88:
                        case 89:
                          carry = 8;
                          product_nibble_low = product_nibble_low - 80;
                        break;
                        default:
                          printf ("Error in _packed_string_integer_multiply: encountered an invalid digit. Exiting now.\n");
                          exit (EXIT_FAILURE);
                        break;
                      }
                      product_packed_byte = product_nibble_low;
                      if (product_packed_byte > 0)
                      {
                        product_is_greater_than_zero = TRUE;
                      }
                      product = packed_string_integer_append_one_digit (product, product_packed_byte);
                    }
                    else
                    {
                      printf ("Internal error in _packed_string_integer_multiply(). temp_num1_integer_component->highest_nibble_position is undefined. Exiting now.\n");
                      exit (EXIT_FAILURE);
                    }
                  }
                }
                temp_num1_integer_component = temp_num1_integer_component->next_number_block;
              } 
              if (carry > 0)
              {
                product_packed_byte = carry;
                if (product_packed_byte > 0)
                {
                  product_is_greater_than_zero = TRUE;
                }
                product = packed_string_integer_append_one_digit (product, product_packed_byte);
                carry = 0;
              }
              if (product_is_greater_than_zero)
              {     
                product = packed_string_integer_set_sign (product, positive);
              }
              temp_product = packed_string_integer_shift_digits_left (product, shift_left_counter); // product = temp_product * 10^i 
              greater_number = packed_string_integer_determine_absolute_value_larger_of_two_integers (temp_product, constant_one);
              if ((greater_number == 0) || (greater_number == 1)) // is temp_product greater than or equal to one? IF yes, then set sign on temp_product to positive.
              {
                temp_product = packed_string_integer_set_sign (temp_product, positive);
              }
              temp_sum                = packed_string_integer_add (temp_sum, sum, temp_product);
              sum                     = packed_string_integer_component_release_memory (sum);
              sum                     = packed_string_integer_copy_number (sum, temp_sum);
              temp_product            = packed_string_integer_release_memory (temp_product);
              temp_sum                = packed_string_integer_release_memory (temp_sum);
              shift_left_counter++;
            }
          }
        } // CLOSING STATEMENT BLOCK: if ((temp_num2_integer_component->highest_digit_position >= 0) && (temp_num2_integer_component->highest_digit_position < MAX_PACKED_NUMBER_BLOCK_SIZE))

        //printf ("\n\nsum = ");
        //packed_string_integer_display (sum, 0);
        //printf ("\n\n");

        temp_num2_integer_component = temp_num2_integer_component->next_number_block;
      } // while (temp_num2 != NULL)
    }
  }
  if (sum != NULL)
  {
    product = sum;
  }
  if (constant_one != NULL)
  {
    constant_one = packed_string_integer_release_memory (constant_one);
  } 
  return product;
}




// *********************************************************************************************************************************************
// * _packed_string_integer_multiply_with_toom3                                                                                                *
// *                                                                                                                                           *
// * This is an internal library to multiply to packed string-based integers together utilizing the Toom-Cook algorithm with k=3 (partitions). *
// *                                                                                                                                           *
// * NOTE: THIS FUNCTION DOES NOT PROPERLY SET THE SIGN ON THE TWO INPUT PACKED, STRING-BASED INTEGERS, M AND N. iT IS AN EXPERIMENTAL,        *
// * INTERNAL ROUTINE AND WORKS BUT I NEED TO ENSURE THE CORRECT SIGN IS APPLIED ON THE PRODUCT IF THIS ROUTINE IS CALLED DIRECTLY. THIS       *
// * SUBROUTINE TREATS M AND N AS POSITIVE INTEGERS WHEN COMPUTING THE PRODUCT.                                                                *
// *********************************************************************************************************************************************
psint * _packed_string_integer_multiply_with_toom3 (psint *product, psint *m, psint *n)
{
  psint *normalized_m, *normalized_n;
  psint *m0, *m1, *m2, *n0, *n1, *n2;
  psint *p0, *p_of_zero, *p_of_one, *p_of_minus_one, *p_of_minus_two, *pinf;
  psint *q0, *q_of_zero, *q_of_one, *q_of_minus_one, *q_of_minus_two, *qinf;
  psint *r0, *r_of_zero, *r_of_one, *r_of_minus_one, *r_of_minus_two, *rinf;
  psint *r1, *r2, *r3, *r4; 
  psint *temp_packed_string_integer, *temp_packed_string_integer2;
  psint *constant_two, *constant_three;
  psint *r0_upper_partition, *r1_lower_partition, *r1_upper_partition, *r2_lower_partition, *r2_upper_partition;
  psint *r3_lower_partition, *r3_upper_partition, *r4_lower_partition, *r4_upper_partition;
  psint *temp_partition_sum, *temp_partition_sum_with_carry;
  psint *carry;
  psnc *temp_num;
  unsigned long long int i, i2, m_number_of_digits, n_number_of_digits, number_of_digits, number_of_digits_appended, temp_number_of_digits1, temp_number_of_digits2;
  unsigned long long int number_of_zeros_to_pad;
  unsigned char state, nibble_low, nibble_high, packed_byte, done;

// *************************************************************************
// * Release any previously used memory otherwise we'd have a memory leak. *
// *************************************************************************
  if (product != NULL)
  {
    product = packed_string_integer_component_release_memory (product); // release the LEFT of DECIMAL number component (if exists) since initializing to zero requires LEFT of DECIMAL number component to be NULL;
  }
  m0 = NULL;
  n0 = NULL;
  m1 = NULL;
  n1 = NULL;
  m2 = NULL;
  n2 = NULL;
  p0 = NULL;
  q0 = NULL;
  r0 = NULL;
  r1 = NULL;
  r2 = NULL;
  r3 = NULL;
  r4 = NULL;
  p_of_zero = NULL;
  q_of_zero = NULL;
  r_of_zero = NULL;
  p_of_one  = NULL;
  q_of_one  = NULL;
  r_of_one  = NULL;
  p_of_minus_one = NULL;
  q_of_minus_one = NULL;
  r_of_minus_one = NULL;
  p_of_minus_two = NULL;
  q_of_minus_two = NULL;
  r_of_minus_two = NULL;
  pinf           = NULL;
  qinf           = NULL;
  rinf           = NULL;
  temp_num       = NULL;
  temp_packed_string_integer  = NULL;
  temp_packed_string_integer2 = NULL;
  temp_partition_sum_with_carry = NULL;
  constant_two   = NULL;
  constant_three = NULL;
  constant_two   = packed_string_integer_set_value (constant_two, "2");
  constant_three = packed_string_integer_set_value (constant_three, "3");
  r0_upper_partition = NULL;
  r1_lower_partition = NULL;
  r1_upper_partition = NULL;
  r2_lower_partition = NULL;
  r2_upper_partition = NULL;
  r3_lower_partition = NULL;
  r3_upper_partition = NULL;
  r4_lower_partition = NULL;
  r4_upper_partition = NULL;
  temp_partition_sum = NULL;
  carry              = NULL;
  normalized_m       = NULL;
  normalized_n       = NULL;
  if ((m != NULL) && (n != NULL) && (constant_two != NULL) && (constant_three != NULL))
  {
    normalized_m = packed_string_integer_copy_number (normalized_m, m);
    normalized_n = packed_string_integer_copy_number (normalized_n, n);
    m_number_of_digits = count_num_digits_in_packed_string_integer (m);
    n_number_of_digits = count_num_digits_in_packed_string_integer (n);
    //printf ("m_number_of_digits = %lld\n", m_number_of_digits);
    //printf ("n_number_of_digits = %lld\n", n_number_of_digits);
    if (m_number_of_digits > n_number_of_digits)
    {
// ******************************************************************************************************
// * Pad a copy of input number "n" with leading zeros to ensure it is same length as input number "m". *
// ******************************************************************************************************
      number_of_zeros_to_pad = m_number_of_digits - n_number_of_digits;
      //printf ("number_of_zeros_to_pad = %lld\n", number_of_zeros_to_pad);
      for (i = 0; i < number_of_zeros_to_pad; i++)
      {
        normalized_n = packed_string_integer_append_one_digit (normalized_n, 0);
      }
    }
    else
    {
      if (n_number_of_digits > m_number_of_digits)
      {
        number_of_zeros_to_pad = n_number_of_digits - m_number_of_digits;
        //printf ("number_of_zeros_to_pad = %lld\n", number_of_zeros_to_pad);
        for (i = 0; i < number_of_zeros_to_pad; i++)
        {
          normalized_m = packed_string_integer_append_one_digit (normalized_m, 0);
        }
      }
    }
    //printf ("normalized_m digit count = %lld\n", count_num_digits_in_packed_string_integer (normalized_m));
    //printf ("normalized_n digit count = %lld\n", count_num_digits_in_packed_string_integer (normalized_n));
    number_of_digits = 0;
    temp_number_of_digits1 = 0;
    temp_number_of_digits2 = 0;
    if (m_number_of_digits > 0)
    {
      if ((m_number_of_digits % 3) == 0)
      {
        temp_number_of_digits1 = m_number_of_digits / 3;
      }
      else
      {
        temp_number_of_digits1 = m_number_of_digits / 3 + 1;
      }
    }
    if (n_number_of_digits > 0)
    {
      if ((n_number_of_digits % 3) == 0)
      {
        temp_number_of_digits2 = n_number_of_digits / 3;
      }
      else
      {
        temp_number_of_digits2 = n_number_of_digits / 3 + 1;
      }
    }
    if (temp_number_of_digits1 >= temp_number_of_digits2)
    {
      number_of_digits = temp_number_of_digits1;
    }
    else
    {
      number_of_digits = temp_number_of_digits2;
    }
    //printf ("For toom-3, partition each input number, m and n, into three blocks comprised of %llu digits per block\n\n", number_of_digits);
    if (normalized_m != NULL)
    {
      if (normalized_m->left_of_decimal != NULL)
      {
        if (number_of_digits > 0)
        {
// ***********************************************************************
// * Copy first subset of digits from normalized_m into first number, m0 *
// ***********************************************************************
          state = 0;
          number_of_digits_appended = 0;
          temp_num = normalized_m->left_of_decimal->first_number_block;
          while ((temp_num != NULL) && (number_of_digits_appended < number_of_digits))
          {
            if (temp_num->highest_digit_position < MAX_PACKED_NUMBER_BLOCK_SIZE)
            {
              i = 0;
              while ((i < temp_num->highest_digit_position) && (number_of_digits_appended < number_of_digits))
              {
                packed_byte = temp_num->packed_number_block[i];
                switch (state)
                {
                  case 0:
                    nibble_low  = packed_byte & 0x0f;
                    m0 = packed_string_integer_append_one_digit (m0, nibble_low);
                    number_of_digits_appended++;
                    state = 1;
                  break;
                  case 1:
                    nibble_high = (packed_byte & 0xf0) >> 4;
                    m0 = packed_string_integer_append_one_digit (m0, nibble_high);
                    number_of_digits_appended++;
                    state = 0;
                    i++;
                  break;
                  default:
                    printf ("Internal error occurred. Exiting now.\n");
                    exit (EXIT_FAILURE);
                  break;
                }
              }
              done = FALSE;
              while ((i == temp_num->highest_digit_position) && (number_of_digits_appended < number_of_digits) && (!done))
              {
                packed_byte = temp_num->packed_number_block[i];
                switch (state)
                {
                  case 0:
                    nibble_low  = packed_byte & 0x0f;
                    m0 = packed_string_integer_append_one_digit (m0, nibble_low);
                    number_of_digits_appended++;
                    if (temp_num->highest_nibble_position == lo)
                    {
                      done = TRUE;
                      i++;
                    }
                    else
                    {
                      state = 1;
                    }
                  break;
                  case 1:
                    if (temp_num->highest_nibble_position == hi)
                    {
                      nibble_high = (packed_byte & 0xf0) >> 4;
                      m0 = packed_string_integer_append_one_digit (m0, nibble_high);
                      number_of_digits_appended++;
                      state = 0;
                      i++;
                    }
                    else
                    {
                      done = TRUE;
                    }
                  break;
                  default:
                    printf ("Internal error occurred. Exiting now.\n");
                    exit (EXIT_FAILURE);
                  break;
                }
              }
            }
            else
            {
              printf ("Internal error occurred. Exiting now.\n");
              exit (EXIT_FAILURE);
            }
            if (i > temp_num->highest_digit_position)
            {
              i = 0;
              temp_num = temp_num->next_number_block;
            }
          } 
          if (number_of_digits_appended > 0)
          {
            m0 = packed_string_integer_set_sign (m0, m->sign);
          }
          else
          {
            m0 = packed_string_integer_component_release_memory (m0);
            m0 = packed_string_integer_initialize_to_zero (m0);
          }
// ************************************************************************
// * Copy second subset of digits from normalized_m into first number, m1 *
// ************************************************************************
          i2 = i;
          number_of_digits_appended = 0;
          while ((temp_num != NULL) && (number_of_digits_appended < number_of_digits))
          {
            if (temp_num->highest_digit_position < MAX_PACKED_NUMBER_BLOCK_SIZE)
            {
              i = i2;
              while ((i < temp_num->highest_digit_position) && (number_of_digits_appended < number_of_digits))
              {
                packed_byte = temp_num->packed_number_block[i];
                switch (state)
                {
                  case 0:
                    nibble_low  = packed_byte & 0x0f;
                    m1 = packed_string_integer_append_one_digit (m1, nibble_low);
                    number_of_digits_appended++;
                    state = 1;
                  break;
                  case 1:
                    nibble_high = (packed_byte & 0xf0) >> 4;
                    m1 = packed_string_integer_append_one_digit (m1, nibble_high);
                    number_of_digits_appended++;
                    state = 0;
                    i++;
                  break;
                  default:
                    printf ("Internal error occurred. Exiting now.\n");
                    exit (EXIT_FAILURE);
                  break;
                }
              }
              done = FALSE;
              while ((i == temp_num->highest_digit_position) && (number_of_digits_appended < number_of_digits) && (!done))
              {
                packed_byte = temp_num->packed_number_block[i];
                switch (state)
                {
                  case 0:
                    nibble_low  = packed_byte & 0x0f;
                    m1 = packed_string_integer_append_one_digit (m1, nibble_low);
                    number_of_digits_appended++;
                    if (temp_num->highest_nibble_position == lo)
                    {
                      done = TRUE;
                      i++;
                    }
                    else
                    {
                      state = 1;
                    }
                  break;
                  case 1:
                    if (temp_num->highest_nibble_position == hi)
                    {
                      nibble_high = (packed_byte & 0xf0) >> 4;
                      m1 = packed_string_integer_append_one_digit (m1, nibble_high);
                      number_of_digits_appended++;
                      state = 0;
                      i++;
                    }
                    else
                    {
                      done = TRUE;
                    }
                  break;
                  default:
                    printf ("Internal error occurred. Exiting now.\n");
                    exit (EXIT_FAILURE);
                  break;
                }
              }
            }
            else
            {
              printf ("Internal error occurred. Exiting now.\n");
              exit (EXIT_FAILURE);
            }
            if (i > temp_num->highest_digit_position)
            {
              temp_num = temp_num->next_number_block;
              i = 0;
              i2 = 0;
            }
          } 
          if (number_of_digits_appended > 0)
          {
            m1 = packed_string_integer_set_sign (m1, m->sign);
          }
          else
          {
            m1 = packed_string_integer_component_release_memory (m1);
            m1 = packed_string_integer_initialize_to_zero (m1);
          }
// ***********************************************************************
// * Copy third subset of digits from normalized_m into first number, m2 *
// ***********************************************************************
          i2 = i;
          number_of_digits_appended = 0;
          while ((temp_num != NULL) && (number_of_digits_appended < number_of_digits))
          {
            if (temp_num->highest_digit_position < MAX_PACKED_NUMBER_BLOCK_SIZE)
            {
              i = i2;
              while ((i < temp_num->highest_digit_position) && (number_of_digits_appended < number_of_digits))
              {
                packed_byte = temp_num->packed_number_block[i];
                switch (state)
                {
                  case 0:
                    nibble_low  = packed_byte & 0x0f;
                    m2 = packed_string_integer_append_one_digit (m2, nibble_low);
                    number_of_digits_appended++;
                    state = 1;
                  break;
                  case 1:
                    nibble_high = (packed_byte & 0xf0) >> 4;
                    m2 = packed_string_integer_append_one_digit (m2, nibble_high);
                    number_of_digits_appended++;
                    state = 0;
                    i++;
                  break;
                  default:
                    printf ("Internal error occurred. Exiting now.\n");
                    exit (EXIT_FAILURE);
                  break;
                }
              }
              done = FALSE;
              while ((i == temp_num->highest_digit_position) && (number_of_digits_appended < number_of_digits) && (!done))
              {
                packed_byte = temp_num->packed_number_block[i];
                switch (state)
                {
                  case 0:
                    nibble_low  = packed_byte & 0x0f;
                    m2 = packed_string_integer_append_one_digit (m2, nibble_low);
                    number_of_digits_appended++;
                    if (temp_num->highest_nibble_position == lo)
                    {
                      i++;
                      done = TRUE;
                    }
                    else
                    {
                      state = 1;
                    }
                  break;
                  case 1:
                    if (temp_num->highest_nibble_position == hi)
                    {
                      nibble_high = (packed_byte & 0xf0) >> 4;
                      m2 = packed_string_integer_append_one_digit (m2, nibble_high);
                      number_of_digits_appended++;
                      state = 0;
                      i++;
                    }
                    else
                    {
                      done = TRUE;
                    }
                  break;
                  default:
                    printf ("Internal error occurred. Exiting now.\n");
                    exit (EXIT_FAILURE);
                  break;
                }
              }
            }
            else
            {
              printf ("Internal error occurred. Exiting now.\n");
              exit (EXIT_FAILURE);
            }
            if (i > temp_num->highest_digit_position)
            {
              temp_num = temp_num->next_number_block;
              i = 0;
              i2 = 0;
            }
          } 
          if (number_of_digits_appended > 0)
          {
            m2 = packed_string_integer_set_sign (m2, m->sign);
          }
          else
          {
            m2 = packed_string_integer_component_release_memory (m2);
            m2 = packed_string_integer_initialize_to_zero (m2);
          }
        }
      }
    }
// **************************
// * Now partition number n *
// **************************
    if (normalized_n != NULL)
    {
      if (normalized_n->left_of_decimal != NULL)
      {
        if (number_of_digits > 0)
        {
// ***********************************************************************
// * Copy first subset of digits from normalized_n into first number, n0 *
// ***********************************************************************
          state = 0;
          number_of_digits_appended = 0;
          temp_num = normalized_n->left_of_decimal->first_number_block;
          while ((temp_num != NULL) && (number_of_digits_appended < number_of_digits))
          {
            if (temp_num->highest_digit_position < MAX_PACKED_NUMBER_BLOCK_SIZE)
            {
              i = 0;
              while ((i < temp_num->highest_digit_position) && (number_of_digits_appended < number_of_digits))
              {
                packed_byte = temp_num->packed_number_block[i];
                switch (state)
                {
                  case 0:
                    nibble_low  = packed_byte & 0x0f;
                    n0 = packed_string_integer_append_one_digit (n0, nibble_low);
                    number_of_digits_appended++;
                    state = 1;
                  break;
                  case 1:
                    nibble_high = (packed_byte & 0xf0) >> 4;
                    n0 = packed_string_integer_append_one_digit (n0, nibble_high);
                    number_of_digits_appended++;
                    state = 0;
                    i++;
                  break;
                  default:
                    printf ("Internal error occurred. Exiting now.\n");
                    exit (EXIT_FAILURE);
                  break;
                }
              }
              done = FALSE;
              while ((i == temp_num->highest_digit_position) && (number_of_digits_appended < number_of_digits) && (!done))
              {
                packed_byte = temp_num->packed_number_block[i];
                switch (state)
                {
                  case 0:
                    nibble_low  = packed_byte & 0x0f;
                    n0 = packed_string_integer_append_one_digit (n0, nibble_low);
                    number_of_digits_appended++;
                    if (temp_num->highest_nibble_position == lo)
                    {
                      done = TRUE;
                      i++;
                    }
                    else
                    {
                      state = 1;
                    }
                  break;
                  case 1:
                    if (temp_num->highest_nibble_position == hi)
                    {
                      nibble_high = (packed_byte & 0xf0) >> 4;
                      n0 = packed_string_integer_append_one_digit (n0, nibble_high);
                      number_of_digits_appended++;
                      state = 0;
                      i++;
                    }
                    else
                    {
                      done = TRUE;
                    }
                  break;
                  default:
                    printf ("Internal error occurred. Exiting now.\n");
                    exit (EXIT_FAILURE);
                  break;
                }
              }
            }
            else
            {
              printf ("Internal error occurred. Exiting now.\n");
              exit (EXIT_FAILURE);
            }
            if (i > temp_num->highest_digit_position)
            {
              i = 0;
              temp_num = temp_num->next_number_block;
            }
          } 
          if (number_of_digits_appended > 0)
          {
            n0 = packed_string_integer_set_sign (n0, n->sign);
          }
          else
          {
            n0 = packed_string_integer_component_release_memory (n0);
            n0 = packed_string_integer_initialize_to_zero (n0);
          }
// ************************************************************************
// * Copy second subset of digits from normalized_n into first number, n1 *
// ************************************************************************
          i2 = i;
          number_of_digits_appended = 0;
          while ((temp_num != NULL) && (number_of_digits_appended < number_of_digits))
          {
            if (temp_num->highest_digit_position < MAX_PACKED_NUMBER_BLOCK_SIZE)
            {
              i = i2;
              while ((i < temp_num->highest_digit_position) && (number_of_digits_appended < number_of_digits))
              {
                packed_byte = temp_num->packed_number_block[i];
                switch (state)
                {
                  case 0:
                    nibble_low  = packed_byte & 0x0f;
                    n1 = packed_string_integer_append_one_digit (n1, nibble_low);
                    number_of_digits_appended++;
                    state = 1;
                  break;
                  case 1:
                    nibble_high = (packed_byte & 0xf0) >> 4;
                    n1 = packed_string_integer_append_one_digit (n1, nibble_high);
                    number_of_digits_appended++;
                    state = 0;
                    i++;
                  break;
                  default:
                    printf ("Internal error occurred. Exiting now.\n");
                    exit (EXIT_FAILURE);
                  break;
                }
              }
              done = FALSE;
              while ((i == temp_num->highest_digit_position) && (number_of_digits_appended < number_of_digits) && (!done))
              {
                packed_byte = temp_num->packed_number_block[i];
                switch (state)
                {
                  case 0:
                    nibble_low  = packed_byte & 0x0f;
                    n1 = packed_string_integer_append_one_digit (n1, nibble_low);
                    number_of_digits_appended++;
                    if (temp_num->highest_nibble_position == lo)
                    {
                      done = TRUE;
                      i++;
                    }
                    else
                    {
                      state = 1;
                    }
                  break;
                  case 1:
                    if (temp_num->highest_nibble_position == hi)
                    {
                      nibble_high = (packed_byte & 0xf0) >> 4;
                      n1 = packed_string_integer_append_one_digit (n1, nibble_high);
                      number_of_digits_appended++;
                      state = 0;
                      i++;
                    }
                    else
                    {
                      done = TRUE;
                    }
                  break;
                  default:
                    printf ("Internal error occurred. Exiting now.\n");
                    exit (EXIT_FAILURE);
                  break;
                }
              }
            }
            else
            {
              printf ("Internal error occurred. Exiting now.\n");
              exit (EXIT_FAILURE);
            }
            if (i > temp_num->highest_digit_position)
            {
              temp_num = temp_num->next_number_block;
              i = 0;
              i2 = 0;
            }
          } 
          if (number_of_digits_appended > 0)
          {
            n1 = packed_string_integer_set_sign (n1, n->sign);
          }
          else
          {
            n1 = packed_string_integer_component_release_memory (n1);
            n1 = packed_string_integer_initialize_to_zero (n1);
          }
// ***********************************************************************
// * Copy third subset of digits from normalized_n into first number, n2 *
// ***********************************************************************
          i2 = i;
          number_of_digits_appended = 0;
          while ((temp_num != NULL) && (number_of_digits_appended < number_of_digits))
          {
            if (temp_num->highest_digit_position < MAX_PACKED_NUMBER_BLOCK_SIZE)
            {
              i = i2;
              while ((i < temp_num->highest_digit_position) && (number_of_digits_appended < number_of_digits))
              {
                packed_byte = temp_num->packed_number_block[i];
                switch (state)
                {
                  case 0:
                    nibble_low  = packed_byte & 0x0f;
                    n2 = packed_string_integer_append_one_digit (n2, nibble_low);
                    number_of_digits_appended++;
                    state = 1;
                  break;
                  case 1:
                    nibble_high = (packed_byte & 0xf0) >> 4;
                    n2 = packed_string_integer_append_one_digit (n2, nibble_high);
                    number_of_digits_appended++;
                    state = 0;
                    i++;
                  break;
                  default:
                    printf ("Internal error occurred. Exiting now.\n");
                    exit (EXIT_FAILURE);
                  break;
                }
              }
              done = FALSE;
              while ((i == temp_num->highest_digit_position) && (number_of_digits_appended < number_of_digits) && (!done))
              {
                packed_byte = temp_num->packed_number_block[i];
                switch (state)
                {
                  case 0:
                    nibble_low  = packed_byte & 0x0f;
                    n2 = packed_string_integer_append_one_digit (n2, nibble_low);
                    number_of_digits_appended++;
                    if (temp_num->highest_nibble_position == lo)
                    {
                      i++;
                      done = TRUE;
                    }
                    else
                    {
                      state = 1;
                    }
                  break;
                  case 1:
                    if (temp_num->highest_nibble_position == hi)
                    {
                      nibble_high = (packed_byte & 0xf0) >> 4;
                      n2 = packed_string_integer_append_one_digit (n2, nibble_high);
                      number_of_digits_appended++;
                      state = 0;
                      i++;
                    }
                    else
                    {
                      done = TRUE;
                    }
                  break;
                  default:
                    printf ("Internal error occurred. Exiting now.\n");
                    exit (EXIT_FAILURE);
                  break;
                }
              }
            }
            else
            {
              printf ("Internal error occurred. Exiting now.\n");
              exit (EXIT_FAILURE);
            }
            if (i > temp_num->highest_digit_position)
            {
              temp_num = temp_num->next_number_block;
              i = 0;
              i2 = 0;
            }
          } 
          if (number_of_digits_appended > 0)
          {
            n2 = packed_string_integer_set_sign (n2, n->sign);
          }
          else
          {
            n2 = packed_string_integer_component_release_memory (n2);
            n2 = packed_string_integer_initialize_to_zero (n2);
          }
        }
      }
    }
    //printf ("m0 = ");
    //packed_string_integer_display (m0, 0);
    //printf ("\n");
    //printf ("m1 = ");
    //packed_string_integer_display (m1, 0);
    //printf ("\n");
    //printf ("m2 = ");
    //packed_string_integer_display (m2, 0);
    //printf ("\n");
    //printf ("n0 = ");
    //packed_string_integer_display (n0, 0);
    //printf ("\n");
    //printf ("n1 = ");
    //packed_string_integer_display (n1, 0);
    //printf ("\n");
    //printf ("n2 = ");
    //packed_string_integer_display (n2, 0);
    //printf ("\n");
    //printf ("m0 digit length: %llu\n", count_num_digits_in_packed_string_integer(m0));
    //printf ("m1 digit length: %llu\n", count_num_digits_in_packed_string_integer(m1));
    //printf ("m2 digit length: %llu\n", count_num_digits_in_packed_string_integer(m2));
    //printf ("n0 digit length: %llu\n", count_num_digits_in_packed_string_integer(n0));
    //printf ("n1 digit length: %llu\n", count_num_digits_in_packed_string_integer(n1));
    //printf ("n2 digit length: %llu\n", count_num_digits_in_packed_string_integer(n2));
    if ((m0 != NULL) && (m1 != NULL) && (m2 != NULL) && (n0 != NULL) && (n1 != NULL) && (n2 != NULL))
    {
      if ((m0->sign != zero) && (m1->sign != zero) && (m2->sign != zero) && (n0->sign != zero) && (n1->sign != zero) && (n2->sign != zero))
      {
        if ((constant_two != NULL) && (constant_three != NULL))
        {
          p0 = packed_string_integer_add (p0, m0, m2);
          p_of_zero = packed_string_integer_copy_number (p_of_zero, m0);
          p_of_one = packed_string_integer_add (p_of_one, p0, m1); 
          p_of_minus_one =  packed_string_integer_subtract (p_of_minus_one, p0, m1); 
          p_of_minus_two = packed_string_integer_add (p_of_minus_two, p_of_minus_one, m2); 
          temp_packed_string_integer = packed_string_integer_multiply_traditional (temp_packed_string_integer, p_of_minus_two, constant_two);
          p_of_minus_two = packed_string_integer_component_release_memory (p_of_minus_two);
          p_of_minus_two = packed_string_integer_subtract (p_of_minus_two, temp_packed_string_integer, m0);
          temp_packed_string_integer = packed_string_integer_release_memory (temp_packed_string_integer);
          pinf = packed_string_integer_copy_number (pinf, m2);
          q0 = packed_string_integer_add (q0, n0, n2);
          q_of_zero = packed_string_integer_copy_number (q_of_zero, n0);
          q_of_one = packed_string_integer_add (q_of_one, q0, n1); 
          q_of_minus_one =  packed_string_integer_subtract (q_of_minus_one, q0, n1); 
          q_of_minus_two = packed_string_integer_add (q_of_minus_two, q_of_minus_one, n2); 
          temp_packed_string_integer = packed_string_integer_multiply_traditional (temp_packed_string_integer, q_of_minus_two, constant_two);
          q_of_minus_two = packed_string_integer_component_release_memory (q_of_minus_two);
          q_of_minus_two = packed_string_integer_subtract (q_of_minus_two, temp_packed_string_integer, n0);
          temp_packed_string_integer = packed_string_integer_release_memory (temp_packed_string_integer);
          qinf = packed_string_integer_copy_number (qinf, n2);
          r_of_zero = packed_string_integer_multiply_traditional (r_of_zero, p_of_zero, q_of_zero);
          r_of_one = packed_string_integer_multiply_traditional (r_of_one, p_of_one, q_of_one);
          r_of_minus_one = packed_string_integer_multiply_traditional (r_of_minus_one, p_of_minus_one, q_of_minus_one);
          r_of_minus_two = packed_string_integer_multiply_traditional (r_of_minus_two, p_of_minus_two, q_of_minus_two);
          rinf = packed_string_integer_multiply_traditional (rinf, pinf, qinf);
          r0 = packed_string_integer_copy_number (r0, r_of_zero);
          r4 = packed_string_integer_copy_number (r4, rinf);
          r3 = packed_string_integer_subtract (r3, r_of_minus_two, r_of_one);
          temp_packed_string_integer = packed_string_integer_divide (temp_packed_string_integer, r3, constant_three);
          r3 = packed_string_integer_component_release_memory (r3);
          r3 = packed_string_integer_copy_number (r3, temp_packed_string_integer);
          temp_packed_string_integer = packed_string_integer_release_memory (temp_packed_string_integer);
          r1 = packed_string_integer_subtract (r1, r_of_one, r_of_minus_one);
          temp_packed_string_integer = packed_string_integer_divide (temp_packed_string_integer, r1, constant_two);
          r1 = packed_string_integer_component_release_memory (r1);
          r1 = packed_string_integer_copy_number (r1, temp_packed_string_integer);
          temp_packed_string_integer = packed_string_integer_release_memory (temp_packed_string_integer);
          r2 = packed_string_integer_subtract (r2, r_of_minus_one, r_of_zero);
          temp_packed_string_integer  = packed_string_integer_subtract (temp_packed_string_integer, r2, r3);
          temp_packed_string_integer2 = packed_string_integer_divide (temp_packed_string_integer2, temp_packed_string_integer, constant_two);
          temp_packed_string_integer = packed_string_integer_release_memory (temp_packed_string_integer);
          temp_packed_string_integer = packed_string_integer_multiply_traditional (temp_packed_string_integer, rinf, constant_two);
          r3 = packed_string_integer_component_release_memory (r3);
          r3 = packed_string_integer_add (r3, temp_packed_string_integer2, temp_packed_string_integer);
          temp_packed_string_integer  = packed_string_integer_release_memory (temp_packed_string_integer);
          temp_packed_string_integer2 = packed_string_integer_release_memory (temp_packed_string_integer2);
          temp_packed_string_integer  = packed_string_integer_add (temp_packed_string_integer, r2, r1);
          r2 = packed_string_integer_component_release_memory (r2);
          r2 = packed_string_integer_subtract (r2, temp_packed_string_integer, r4);   
          temp_packed_string_integer  = packed_string_integer_component_release_memory (temp_packed_string_integer);
          temp_packed_string_integer = packed_string_integer_subtract (temp_packed_string_integer, r1, r3);
          r1 = packed_string_integer_component_release_memory (r1);
          r1 = packed_string_integer_copy_number (r1, temp_packed_string_integer);
          temp_packed_string_integer = packed_string_integer_release_memory (temp_packed_string_integer);
        }
// ******************************************************************************************************
// * RECOMPOSITION Step 1a: copy number_of_digits digits from r0 into result (multiplication of m * n). *
// ******************************************************************************************************
        if (r0 != NULL)
        {
          if (r0->left_of_decimal != NULL)
          {
            state = 0;
            number_of_digits_appended = 0;
            temp_num = r0->left_of_decimal->first_number_block;
            while ((temp_num != NULL) && (number_of_digits_appended < number_of_digits))
            {
              if (temp_num->highest_digit_position < MAX_PACKED_NUMBER_BLOCK_SIZE)
              {
                i = 0;
                while ((i < temp_num->highest_digit_position) && (number_of_digits_appended < number_of_digits))
                {
                  packed_byte = temp_num->packed_number_block[i];
                  switch (state)
                  {
                    case 0:
                      nibble_low  = packed_byte & 0x0f;
                      product = packed_string_integer_append_one_digit (product, nibble_low);
                      number_of_digits_appended++;
                      state = 1;
                    break;
                    case 1:
                      nibble_high = (packed_byte & 0xf0) >> 4;
                      product = packed_string_integer_append_one_digit (product, nibble_high);
                      number_of_digits_appended++;
                      state = 0;
                      i++;
                    break;
                    default:
                      printf ("Internal error occurred. Exiting now.\n");
                      exit (EXIT_FAILURE);
                    break;
                  }
                }
                done = FALSE;
                while ((i == temp_num->highest_digit_position) && (number_of_digits_appended < number_of_digits) && (!done))
                {
                  packed_byte = temp_num->packed_number_block[i];
                  switch (state)
                  {
                    case 0:
                      nibble_low  = packed_byte & 0x0f;
                      product = packed_string_integer_append_one_digit (product, nibble_low);
                      number_of_digits_appended++;
                      if (temp_num->highest_nibble_position == lo)
                      {
                        done = TRUE;
                        i++;
                      }
                      else
                      {
                        state = 1;
                      }
                    break;
                    case 1:
                      if (temp_num->highest_nibble_position == hi)
                      {
                        nibble_high = (packed_byte & 0xf0) >> 4;
                        product = packed_string_integer_append_one_digit (product, nibble_high);
                        number_of_digits_appended++;
                        state = 0;
                        i++;
                      }
                      else
                      {
                        done = TRUE;
                      }
                    break;
                    default:
                      printf ("Internal error occurred. Exiting now.\n");
                      exit (EXIT_FAILURE);
                    break;
                  }
                }
              }
              else
              {
                printf ("Internal error occurred. Exiting now.\n");
                exit (EXIT_FAILURE);
              }
              if (i > temp_num->highest_digit_position)
              {
                i = 0;
                temp_num = temp_num->next_number_block;
              }
            } 
// *********************************************************************************
// * RECOMPOSITION Step 1b: copy remaining digits from r0 into r0_upper_partition. *
// *********************************************************************************
            i2 = i;
            number_of_digits_appended = 0;
            while ((temp_num != NULL) && (number_of_digits_appended < number_of_digits))
            {
              if (temp_num->highest_digit_position < MAX_PACKED_NUMBER_BLOCK_SIZE)
              {
                i = i2;
                while ((i < temp_num->highest_digit_position) && (number_of_digits_appended < number_of_digits))
                {
                  packed_byte = temp_num->packed_number_block[i];
                  switch (state)
                  {
                    case 0:
                      nibble_low  = packed_byte & 0x0f;
                      r0_upper_partition = packed_string_integer_append_one_digit (r0_upper_partition, nibble_low);
                      number_of_digits_appended++;
                      state = 1;
                    break;
                    case 1:
                      nibble_high = (packed_byte & 0xf0) >> 4;
                      r0_upper_partition = packed_string_integer_append_one_digit (r0_upper_partition, nibble_high);
                      number_of_digits_appended++;
                      state = 0;
                      i++;
                    break;
                    default:
                      printf ("Internal error occurred. Exiting now.\n");
                      exit (EXIT_FAILURE);
                    break;
                  }
                }
                done = FALSE;
                while ((i == temp_num->highest_digit_position) && (number_of_digits_appended < number_of_digits) && (!done))
                {
                  packed_byte = temp_num->packed_number_block[i];
                  switch (state)
                  {
                    case 0:
                      nibble_low  = packed_byte & 0x0f;
                      r0_upper_partition = packed_string_integer_append_one_digit (r0_upper_partition, nibble_low);
                      number_of_digits_appended++;
                      if (temp_num->highest_nibble_position == lo)
                      {
                        done = TRUE;
                        i++;
                      }
                      else
                      {
                        state = 1;
                      }
                    break;
                    case 1:
                      if (temp_num->highest_nibble_position == hi)
                      {
                        nibble_high = (packed_byte & 0xf0) >> 4;
                        r0_upper_partition = packed_string_integer_append_one_digit (r0_upper_partition, nibble_high);
                        number_of_digits_appended++;
                        state = 0;
                        i++;
                      }
                      else
                      {
                        done = TRUE;
                      }
                    break;
                    default:
                      printf ("Internal error occurred. Exiting now.\n");
                      exit (EXIT_FAILURE);
                    break;
                  }
                }
              }
              else
              {
                printf ("Internal error occurred. Exiting now.\n");
                exit (EXIT_FAILURE);
              }
              if (i > temp_num->highest_digit_position)
              {
                temp_num = temp_num->next_number_block;
                i = 0;
                i2 = 0;
              }
            } 
            r0_upper_partition = packed_string_integer_set_sign (r0_upper_partition, positive);
          }   
        }
// ****************************************************************************************
// * RECOMPOSITION Step 2a: copy NUMBER_OF_DIGITS digits from r1 into r1_lower_partition. *
// ****************************************************************************************
        if (r1 != NULL)
        {
          if (r1->left_of_decimal != NULL)
          {
            state = 0;
            number_of_digits_appended = 0;
            temp_num = r1->left_of_decimal->first_number_block;
            while ((temp_num != NULL) && (number_of_digits_appended < number_of_digits))
            {
              if (temp_num->highest_digit_position < MAX_PACKED_NUMBER_BLOCK_SIZE)
              {
                i = 0;
                while ((i < temp_num->highest_digit_position) && (number_of_digits_appended < number_of_digits))
                {
                  packed_byte = temp_num->packed_number_block[i];
                  switch (state)
                  {
                    case 0:
                      nibble_low  = packed_byte & 0x0f;
                      r1_lower_partition = packed_string_integer_append_one_digit (r1_lower_partition, nibble_low);
                      number_of_digits_appended++;
                      state = 1;
                    break;
                    case 1:
                      nibble_high = (packed_byte & 0xf0) >> 4;
                      r1_lower_partition = packed_string_integer_append_one_digit (r1_lower_partition, nibble_high);
                      number_of_digits_appended++;
                      state = 0;
                      i++;
                    break;
                    default:
                      printf ("Internal error occurred. Exiting now.\n");
                      exit (EXIT_FAILURE);
                    break;
                  }
                }
                done = FALSE;
                while ((i == temp_num->highest_digit_position) && (number_of_digits_appended < number_of_digits) && (!done))
                {
                  packed_byte = temp_num->packed_number_block[i];
                  switch (state)
                  {
                    case 0:
                      nibble_low  = packed_byte & 0x0f;
                      r1_lower_partition = packed_string_integer_append_one_digit (r1_lower_partition, nibble_low);
                      number_of_digits_appended++;
                      if (temp_num->highest_nibble_position == lo)
                      {
                        done = TRUE;
                        i++;
                      }
                      else
                      {
                        state = 1;
                      }
                    break;
                    case 1:
                      if (temp_num->highest_nibble_position == hi)
                      {
                        nibble_high = (packed_byte & 0xf0) >> 4;
                        r1_lower_partition = packed_string_integer_append_one_digit (r1_lower_partition, nibble_high);
                        number_of_digits_appended++;
                        state = 0;
                        i++;
                      }
                      else
                      {
                        done = TRUE;
                      }
                    break;
                    default:
                      printf ("Internal error occurred. Exiting now.\n");
                      exit (EXIT_FAILURE);
                    break;
                  }
                }
              }
              else
              {
                printf ("Internal error occurred. Exiting now.\n");
                exit (EXIT_FAILURE);
              }
              if (i > temp_num->highest_digit_position)
              {
                i = 0;
                temp_num = temp_num->next_number_block;
              }
            } 
            r1_lower_partition = packed_string_integer_set_sign (r1_lower_partition, positive);
// *********************************************************************************
// * RECOMPOSITION Step 2b: copy remaining digits from r1 into r1_upper_partition. *
// *********************************************************************************
            i2 = i;
            number_of_digits_appended = 0;
            while ((temp_num != NULL) && (number_of_digits_appended < number_of_digits))
            {
              if (temp_num->highest_digit_position < MAX_PACKED_NUMBER_BLOCK_SIZE)
              {
                i = i2;
                while ((i < temp_num->highest_digit_position) && (number_of_digits_appended < number_of_digits))
                {
                  packed_byte = temp_num->packed_number_block[i];
                  switch (state)
                  {
                    case 0:
                      nibble_low  = packed_byte & 0x0f;
                      r1_upper_partition = packed_string_integer_append_one_digit (r1_upper_partition, nibble_low);
                      number_of_digits_appended++;
                      state = 1;
                    break;
                    case 1:
                      nibble_high = (packed_byte & 0xf0) >> 4;
                      r1_upper_partition = packed_string_integer_append_one_digit (r1_upper_partition, nibble_high);
                      number_of_digits_appended++;
                      state = 0;
                      i++;
                    break;
                    default:
                      printf ("Internal error occurred. Exiting now.\n");
                      exit (EXIT_FAILURE);
                    break;
                  }
                }
                done = FALSE;
                while ((i == temp_num->highest_digit_position) && (number_of_digits_appended < number_of_digits) && (!done))
                {
                  packed_byte = temp_num->packed_number_block[i];
                  switch (state)
                  {
                    case 0:
                      nibble_low  = packed_byte & 0x0f;
                      r1_upper_partition = packed_string_integer_append_one_digit (r1_upper_partition, nibble_low);
                      number_of_digits_appended++;
                      if (temp_num->highest_nibble_position == lo)
                      {
                        done = TRUE;
                        i++;
                      }
                      else
                      {
                        state = 1;
                      }
                    break;
                    case 1:
                      if (temp_num->highest_nibble_position == hi)
                      {
                        nibble_high = (packed_byte & 0xf0) >> 4;
                        r1_upper_partition = packed_string_integer_append_one_digit (r1_upper_partition, nibble_high);
                        number_of_digits_appended++;
                        state = 0;
                        i++;
                      }
                      else
                      {
                        done = TRUE;
                      }
                    break;
                    default:
                      printf ("Internal error occurred. Exiting now.\n");
                      exit (EXIT_FAILURE);
                    break;
                  }
                }
              }
              else
              {
                printf ("Internal error occurred. Exiting now.\n");
                exit (EXIT_FAILURE);
              }
              if (i > temp_num->highest_digit_position)
              {
                temp_num = temp_num->next_number_block;
                i = 0;
                i2 = 0;
              }
            } 
            r1_upper_partition = packed_string_integer_set_sign (r1_upper_partition, positive);
          }
        }
// ****************************************************************************************
// * RECOMPOSITION Step 3a: copy NUMBER_OF_DIGITS digits from r2 into r2_lower_partition. *
// ****************************************************************************************
        if (r2 != NULL)
        {
          if (r2->left_of_decimal != NULL)
          {
            state = 0;
            number_of_digits_appended = 0;
            temp_num = r2->left_of_decimal->first_number_block;
            while ((temp_num != NULL) && (number_of_digits_appended < number_of_digits))
            {
              if (temp_num->highest_digit_position < MAX_PACKED_NUMBER_BLOCK_SIZE)
              {
                i = 0;
                while ((i < temp_num->highest_digit_position) && (number_of_digits_appended < number_of_digits))
                {
                  packed_byte = temp_num->packed_number_block[i];
                  switch (state)
                  {
                    case 0:
                      nibble_low  = packed_byte & 0x0f;
                      r2_lower_partition = packed_string_integer_append_one_digit (r2_lower_partition, nibble_low);
                      number_of_digits_appended++;
                      state = 1;
                    break;
                    case 1:
                      nibble_high = (packed_byte & 0xf0) >> 4;
                      r2_lower_partition = packed_string_integer_append_one_digit (r2_lower_partition, nibble_high);
                      number_of_digits_appended++;
                      state = 0;
                      i++;
                    break;
                    default:
                      printf ("Internal error occurred. Exiting now.\n");
                      exit (EXIT_FAILURE);
                    break;
                  }
                }
                done = FALSE;
                while ((i == temp_num->highest_digit_position) && (number_of_digits_appended < number_of_digits) && (!done))
                {
                  packed_byte = temp_num->packed_number_block[i];
                  switch (state)
                  {
                    case 0:
                      nibble_low  = packed_byte & 0x0f;
                      r2_lower_partition = packed_string_integer_append_one_digit (r2_lower_partition, nibble_low);
                      number_of_digits_appended++;
                      if (temp_num->highest_nibble_position == lo)
                      {
                        done = TRUE;
                        i++;
                      }
                      else
                      {
                        state = 1;
                      }
                    break;
                    case 1:
                      if (temp_num->highest_nibble_position == hi)
                      {
                        nibble_high = (packed_byte & 0xf0) >> 4;
                        r2_lower_partition = packed_string_integer_append_one_digit (r2_lower_partition, nibble_high);
                        number_of_digits_appended++;
                        state = 0;
                        i++;
                      }
                      else
                      {
                        done = TRUE;
                      }
                    break;
                    default:
                      printf ("Internal error occurred. Exiting now.\n");
                      exit (EXIT_FAILURE);
                    break;
                  }
                }
              }
              else
              {
                printf ("Internal error occurred. Exiting now.\n");
                exit (EXIT_FAILURE);
              }
              if (i > temp_num->highest_digit_position)
              {
                i = 0;
                temp_num = temp_num->next_number_block;
              }
            } 
            r2_lower_partition = packed_string_integer_set_sign (r2_lower_partition, positive);
// *********************************************************************************
// * RECOMPOSITION Step 3b: copy remaining digits from r2 into r2_upper_partition. *
// *********************************************************************************
            i2 = i;
            number_of_digits_appended = 0;
            while ((temp_num != NULL) && (number_of_digits_appended < number_of_digits))
            {
              if (temp_num->highest_digit_position < MAX_PACKED_NUMBER_BLOCK_SIZE)
              {
                i = i2;
                while ((i < temp_num->highest_digit_position) && (number_of_digits_appended < number_of_digits))
                {
                  packed_byte = temp_num->packed_number_block[i];
                  switch (state)
                  {
                    case 0:
                      nibble_low  = packed_byte & 0x0f;
                      r2_upper_partition = packed_string_integer_append_one_digit (r2_upper_partition, nibble_low);
                      number_of_digits_appended++;
                      state = 1;
                    break;
                    case 1:
                      nibble_high = (packed_byte & 0xf0) >> 4;
                      r2_upper_partition = packed_string_integer_append_one_digit (r2_upper_partition, nibble_high);
                      number_of_digits_appended++;
                      state = 0;
                      i++;
                    break;
                    default:
                      printf ("Internal error occurred. Exiting now.\n");
                      exit (EXIT_FAILURE);
                    break;
                  }
                }
                done = FALSE;
                while ((i == temp_num->highest_digit_position) && (number_of_digits_appended < number_of_digits) && (!done))
                {
                  packed_byte = temp_num->packed_number_block[i];
                  switch (state)
                  {
                    case 0:
                      nibble_low  = packed_byte & 0x0f;
                      r2_upper_partition = packed_string_integer_append_one_digit (r2_upper_partition, nibble_low);
                      number_of_digits_appended++;
                      if (temp_num->highest_nibble_position == lo)
                      {
                        done = TRUE;
                        i++;
                      }
                      else
                      {
                        state = 1;
                      }
                    break;
                    case 1:
                      if (temp_num->highest_nibble_position == hi)
                      {
                        nibble_high = (packed_byte & 0xf0) >> 4;
                        r2_upper_partition = packed_string_integer_append_one_digit (r2_upper_partition, nibble_high);
                        number_of_digits_appended++;
                        state = 0;
                        i++;
                      }
                      else
                      {
                        done = TRUE;
                      }
                    break;
                    default:
                      printf ("Internal error occurred. Exiting now.\n");
                      exit (EXIT_FAILURE);
                    break;
                  }
                }
              }
              else
              {
                printf ("Internal error occurred. Exiting now.\n");
                exit (EXIT_FAILURE);
              }
              if (i > temp_num->highest_digit_position)
              {
                temp_num = temp_num->next_number_block;
                i = 0;
                i2 = 0;
              }
            } 
            r2_upper_partition = packed_string_integer_set_sign (r2_upper_partition, positive);
          }
        }
// ****************************************************************************************
// * RECOMPOSITION Step 4a: copy NUMBER_OF_DIGITS digits from r3 into r3_lower_partition. *
// ****************************************************************************************
        if (r3 != NULL)
        {
          if (r3->left_of_decimal != NULL)
          {
            state = 0;
            number_of_digits_appended = 0;
            temp_num = r3->left_of_decimal->first_number_block;
            while ((temp_num != NULL) && (number_of_digits_appended < number_of_digits))
            {
              if (temp_num->highest_digit_position < MAX_PACKED_NUMBER_BLOCK_SIZE)
              {
                i = 0;
                while ((i < temp_num->highest_digit_position) && (number_of_digits_appended < number_of_digits))
                {
                  packed_byte = temp_num->packed_number_block[i];
                  switch (state)
                  {
                    case 0:
                      nibble_low  = packed_byte & 0x0f;
                      r3_lower_partition = packed_string_integer_append_one_digit (r3_lower_partition, nibble_low);
                      number_of_digits_appended++;
                      state = 1;
                    break;
                    case 1:
                      nibble_high = (packed_byte & 0xf0) >> 4;
                      r3_lower_partition = packed_string_integer_append_one_digit (r3_lower_partition, nibble_high);
                      number_of_digits_appended++;
                      state = 0;
                      i++;
                    break;
                    default:
                      printf ("Internal error occurred. Exiting now.\n");
                      exit (EXIT_FAILURE);
                    break;
                  }
                }
                done = FALSE;
                while ((i == temp_num->highest_digit_position) && (number_of_digits_appended < number_of_digits) && (!done))
                {
                  packed_byte = temp_num->packed_number_block[i];
                  switch (state)
                  {
                    case 0:
                      nibble_low  = packed_byte & 0x0f;
                      r3_lower_partition = packed_string_integer_append_one_digit (r3_lower_partition, nibble_low);
                      number_of_digits_appended++;
                      if (temp_num->highest_nibble_position == lo)
                      {
                        done = TRUE;
                        i++;
                      }
                      else
                      {
                        state = 1;
                      }
                    break;
                    case 1:
                      if (temp_num->highest_nibble_position == hi)
                      {
                        nibble_high = (packed_byte & 0xf0) >> 4;
                        r3_lower_partition = packed_string_integer_append_one_digit (r3_lower_partition, nibble_high);
                        number_of_digits_appended++;
                        state = 0;
                        i++;
                      }
                      else
                      {
                        done = TRUE;
                      }
                    break;
                    default:
                      printf ("Internal error occurred. Exiting now.\n");
                      exit (EXIT_FAILURE);
                    break;
                  }
                }
              }
              else
              {
                printf ("Internal error occurred. Exiting now.\n");
                exit (EXIT_FAILURE);
              }
              if (i > temp_num->highest_digit_position)
              {
                i = 0;
                temp_num = temp_num->next_number_block;
              }
            } 
            r3_lower_partition = packed_string_integer_set_sign (r3_lower_partition, positive);
// *********************************************************************************
// * RECOMPOSITION Step 4b: copy remaining digits from r3 into r3_upper_partition. *
// *********************************************************************************
            i2 = i;
            number_of_digits_appended = 0;
            while ((temp_num != NULL) && (number_of_digits_appended < number_of_digits))
            {
              if (temp_num->highest_digit_position < MAX_PACKED_NUMBER_BLOCK_SIZE)
              {
                i = i2;
                while ((i < temp_num->highest_digit_position) && (number_of_digits_appended < number_of_digits))
                {
                  packed_byte = temp_num->packed_number_block[i];
                  switch (state)
                  {
                    case 0:
                      nibble_low  = packed_byte & 0x0f;
                      r3_upper_partition = packed_string_integer_append_one_digit (r3_upper_partition, nibble_low);
                      number_of_digits_appended++;
                      state = 1;
                    break;
                    case 1:
                      nibble_high = (packed_byte & 0xf0) >> 4;
                      r3_upper_partition = packed_string_integer_append_one_digit (r3_upper_partition, nibble_high);
                      number_of_digits_appended++;
                      state = 0;
                      i++;
                    break;
                    default:
                      printf ("Internal error occurred. Exiting now.\n");
                      exit (EXIT_FAILURE);
                    break;
                  }
                }
                done = FALSE;
                while ((i == temp_num->highest_digit_position) && (number_of_digits_appended < number_of_digits) && (!done))
                {
                  packed_byte = temp_num->packed_number_block[i];
                  switch (state)
                  {
                    case 0:
                      nibble_low  = packed_byte & 0x0f;
                      r3_upper_partition = packed_string_integer_append_one_digit (r3_upper_partition, nibble_low);
                      number_of_digits_appended++;
                      if (temp_num->highest_nibble_position == lo)
                      {
                        done = TRUE;
                        i++;
                      }
                      else
                      {
                        state = 1;
                      }
                    break;
                    case 1:
                      if (temp_num->highest_nibble_position == hi)
                      {
                        nibble_high = (packed_byte & 0xf0) >> 4;
                        r3_upper_partition = packed_string_integer_append_one_digit (r3_upper_partition, nibble_high);
                        number_of_digits_appended++;
                        state = 0;
                        i++;
                      }
                      else
                      {
                        done = TRUE;
                      }
                    break;
                    default:
                      printf ("Internal error occurred. Exiting now.\n");
                      exit (EXIT_FAILURE);
                    break;
                  }
                }
              }
              else
              {
                printf ("Internal error occurred. Exiting now.\n");
                exit (EXIT_FAILURE);
              }
              if (i > temp_num->highest_digit_position)
              {
                temp_num = temp_num->next_number_block;
                i = 0;
                i2 = 0;
              }
            } 
            r3_upper_partition = packed_string_integer_set_sign (r3_upper_partition, positive);
          }
        }
// ****************************************************************************************
// * RECOMPOSITION Step 5a: copy NUMBER_OF_DIGITS digits from r4 into r4_lower_partition. *
// ****************************************************************************************
        if (r4 != NULL)
        {
          if (r4->left_of_decimal != NULL)
          {
            state = 0;
            number_of_digits_appended = 0;
            temp_num = r4->left_of_decimal->first_number_block;
            while ((temp_num != NULL) && (number_of_digits_appended < number_of_digits))
            {
              if (temp_num->highest_digit_position < MAX_PACKED_NUMBER_BLOCK_SIZE)
              {
                i = 0;
                while ((i < temp_num->highest_digit_position) && (number_of_digits_appended < number_of_digits))
                {
                  packed_byte = temp_num->packed_number_block[i];
                  switch (state)
                  {
                    case 0:
                      nibble_low = packed_byte & 0x0f;
                      r4_lower_partition = packed_string_integer_append_one_digit (r4_lower_partition, nibble_low);
                      number_of_digits_appended++;
                      state = 1;
                    break;
                    case 1:
                      nibble_high = (packed_byte & 0xf0) >> 4;
                      r4_lower_partition = packed_string_integer_append_one_digit (r4_lower_partition, nibble_high);
                      number_of_digits_appended++;
                      state = 0;
                      i++;
                    break;
                    default:
                      printf ("Internal error occurred. Exiting now.\n");
                      exit (EXIT_FAILURE);
                    break;
                  }
                }
                done = FALSE;
                while ((i == temp_num->highest_digit_position) && (number_of_digits_appended < number_of_digits) && (!done))
                {
                  packed_byte = temp_num->packed_number_block[i];
                  switch (state)
                  {
                    case 0:
                      nibble_low  = packed_byte & 0x0f;
                      r4_lower_partition = packed_string_integer_append_one_digit (r4_lower_partition, nibble_low);
                      number_of_digits_appended++;
                      if (temp_num->highest_nibble_position == lo)
                      {
                        done = TRUE;
                        i++;
                      }
                      else
                      {
                        state = 1;
                      }
                    break;
                    case 1:
                      if (temp_num->highest_nibble_position == hi)
                      {
                        nibble_high = (packed_byte & 0xf0) >> 4;
                        r4_lower_partition = packed_string_integer_append_one_digit (r4_lower_partition, nibble_high);
                        number_of_digits_appended++;
                        state = 0;
                        i++;
                      }
                      else
                      {
                        done = TRUE;
                      }
                    break;
                    default:
                      printf ("Internal error occurred. Exiting now.\n");
                      exit (EXIT_FAILURE);
                    break;
                  }
                }
              }
              else
              {
                printf ("Internal error occurred. Exiting now.\n");
                exit (EXIT_FAILURE);
              }
              if (i > temp_num->highest_digit_position)
              {
                i = 0;
                temp_num = temp_num->next_number_block;
              }
            } 
            r4_lower_partition = packed_string_integer_set_sign (r4_lower_partition, positive);
// *********************************************************************************
// * RECOMPOSITION Step 5b: copy remaining digits from r4 into r4_upper_partition. *
// *********************************************************************************
            i2 = i;
            number_of_digits_appended = 0;
            while ((temp_num != NULL) && (number_of_digits_appended < number_of_digits))
            {
              if (temp_num->highest_digit_position < MAX_PACKED_NUMBER_BLOCK_SIZE)
              {
                i = i2;
                while ((i < temp_num->highest_digit_position) && (number_of_digits_appended < number_of_digits))
                {
                  packed_byte = temp_num->packed_number_block[i];
                  switch (state)
                  {
                    case 0:
                      nibble_low  = packed_byte & 0x0f;
                      r4_upper_partition = packed_string_integer_append_one_digit (r4_upper_partition, nibble_low);
                      number_of_digits_appended++;
                      state = 1;
                    break;
                    case 1:
                      nibble_high = (packed_byte & 0xf0) >> 4;
                      r4_upper_partition = packed_string_integer_append_one_digit (r4_upper_partition, nibble_high);
                      number_of_digits_appended++;
                      state = 0;
                      i++;
                    break;
                    default:
                      printf ("Internal error occurred. Exiting now.\n");
                      exit (EXIT_FAILURE);
                    break;
                  }
                }
                done = FALSE;
                while ((i == temp_num->highest_digit_position) && (number_of_digits_appended < number_of_digits) && (!done))
                {
                  packed_byte = temp_num->packed_number_block[i];
                  switch (state)
                  {
                    case 0:
                      nibble_low  = packed_byte & 0x0f;
                      r4_upper_partition = packed_string_integer_append_one_digit (r4_upper_partition, nibble_low);
                      number_of_digits_appended++;
                      if (temp_num->highest_nibble_position == lo)
                      {
                        done = TRUE;
                        i++;
                      }
                      else
                      {
                        state = 1;
                      }
                    break;
                    case 1:
                      if (temp_num->highest_nibble_position == hi)
                      {
                        nibble_high = (packed_byte & 0xf0) >> 4;
                        r4_upper_partition = packed_string_integer_append_one_digit (r4_upper_partition, nibble_high);
                        number_of_digits_appended++;
                        state = 0;
                        i++;
                      }
                      else
                      {
                        done = TRUE;
                      }
                    break;
                    default:
                      printf ("Internal error occurred. Exiting now.\n");
                      exit (EXIT_FAILURE);
                    break;
                  }
                }
              }
              else
              {
                printf ("Internal error occurred. Exiting now.\n");
                exit (EXIT_FAILURE);
              }
              if (i > temp_num->highest_digit_position)
              {
                temp_num = temp_num->next_number_block;
                i = 0;
                i2 = 0;
              }
            } 
            r4_upper_partition = packed_string_integer_set_sign (r4_upper_partition, positive);
          }
        }
// ***********************************************************************************************************************************************
// * RECOMPOSITION Step 6: add r0_upper_partion and r1_lower_partion. Then copy NUMBER_OF_DIGITS digits from the resultant sum into the product. * 
// ***********************************************************************************************************************************************
        if ((r0_upper_partition != NULL) && (r1_lower_partition != NULL))
        {
          temp_partition_sum = packed_string_integer_add (temp_partition_sum, r0_upper_partition, r1_lower_partition);
          if (temp_partition_sum != NULL)
          {
            if (temp_partition_sum->left_of_decimal != NULL)
            {
              i = 0;
              state = 0;
              number_of_digits_appended = 0;
              temp_num = temp_partition_sum->left_of_decimal->first_number_block;
              while ((temp_num != NULL) && (number_of_digits_appended < number_of_digits))
              {
                if (temp_num->highest_digit_position < MAX_PACKED_NUMBER_BLOCK_SIZE)
                {
                  i = 0;
                  while ((i < temp_num->highest_digit_position) && (number_of_digits_appended < number_of_digits))
                  {
                    packed_byte = temp_num->packed_number_block[i];
                    switch (state)
                    {
                      case 0:
                        nibble_low  = packed_byte & 0x0f;
                        product = packed_string_integer_append_one_digit (product, nibble_low);
                        number_of_digits_appended++;
                        state = 1;
                      break;
                      case 1:
                        nibble_high = (packed_byte & 0xf0) >> 4;
                        product = packed_string_integer_append_one_digit (product, nibble_high);
                        number_of_digits_appended++;
                        state = 0;
                        i++;
                      break;
                      default:
                        printf ("Internal error occurred. Exiting now.\n");
                        exit (EXIT_FAILURE);
                      break;
                    }
                  }
                  done = FALSE;
                  while ((i == temp_num->highest_digit_position) && (number_of_digits_appended < number_of_digits) && (!done))
                  {
                    packed_byte = temp_num->packed_number_block[i];
                    switch (state)
                    {
                      case 0:
                        nibble_low  = packed_byte & 0x0f;
                        product = packed_string_integer_append_one_digit (product, nibble_low);
                        number_of_digits_appended++;
                        if (temp_num->highest_nibble_position == lo)
                        {
                          done = TRUE;
                          i++;
                        }
                        else
                        {
                          state = 1;
                        }
                      break;
                      case 1:
                        if (temp_num->highest_nibble_position == hi)
                        {
                          nibble_high = (packed_byte & 0xf0) >> 4;
                          product = packed_string_integer_append_one_digit (product, nibble_high);
                          number_of_digits_appended++;
                          state = 0;
                          i++;
                        }
                        else
                        {
                          done = TRUE;
                        }
                      break;
                      default:
                        printf ("Internal error occurred. Exiting now.\n");
                        exit (EXIT_FAILURE);
                      break;
                    }
                  }
                }
                else
                {
                  printf ("Internal error occurred. Exiting now.\n");
                  exit (EXIT_FAILURE);
                }
                if (i > temp_num->highest_digit_position)
                {
                  i = 0;
                  temp_num = temp_num->next_number_block;
                }
              } 
// ********************************************************************************************
// * Now copy over any reamining digits. These remaining digits represent the carry (if any). *
// ********************************************************************************************
              i2 = i;
              while (temp_num != NULL)
              {
                if (temp_num->highest_digit_position < MAX_PACKED_NUMBER_BLOCK_SIZE)
                {
                  i = i2;
                  while (i < temp_num->highest_digit_position)
                  {
                    packed_byte = temp_num->packed_number_block[i];
                    switch (state)
                    {
                      case 0:
                        nibble_low  = packed_byte & 0x0f;
                        carry = packed_string_integer_append_one_digit (carry, nibble_low);
                        state = 1;
                      break;
                      case 1:
                        nibble_high = (packed_byte & 0xf0) >> 4;
                        carry = packed_string_integer_append_one_digit (carry, nibble_high);
                        state = 0;
                        i++;
                      break;
                      default:
                        printf ("Internal error occurred. Exiting now.\n");
                        exit (EXIT_FAILURE);
                      break;
                    }
                  }
                  done = FALSE;
                  while ((i == temp_num->highest_digit_position) && (!done))
                  {
                    packed_byte = temp_num->packed_number_block[i];
                    switch (state)
                    {
                      case 0:
                        nibble_low  = packed_byte & 0x0f;
                        carry = packed_string_integer_append_one_digit (carry, nibble_low);
                        if (temp_num->highest_nibble_position == lo)
                        {
                          i++;
                          done = TRUE;
                        }
                        else
                        {
                          state = 1;
                        }
                      break;
                      case 1:
                        if (temp_num->highest_nibble_position == hi)
                        {
                          nibble_high = (packed_byte & 0xf0) >> 4;
                          carry = packed_string_integer_append_one_digit (carry, nibble_high);
                          state = 0;
                          i++;
                        }
                        else
                        {
                          done = TRUE;
                        }
                      break;
                      default:
                        printf ("Internal error occurred. Exiting now.\n");
                        exit (EXIT_FAILURE);
                      break;
                    }
                  }
                }
                else
                {
                  printf ("Internal error occurred. Exiting now.\n");
                  exit (EXIT_FAILURE);
                }
                if (i > temp_num->highest_digit_position)
                {
                  temp_num = temp_num->next_number_block;
                  i = 0;
                  i2 = 0;
                }
              } 
              if (carry != NULL)
              {
                carry = packed_string_integer_set_sign (carry, positive);
              }
            }   
            temp_partition_sum = packed_string_integer_release_memory (temp_partition_sum);
          }
        }
// ***********************************************************************************************************************************************
// * RECOMPOSITION Step 7: add r1_upper_partion and r2_lower_partion. Then copy NUMBER_OF_DIGITS digits from the resultant sum into the product. * 
// ***********************************************************************************************************************************************
        if ((r1_upper_partition != NULL) && (r2_lower_partition != NULL))
        {
          temp_partition_sum = packed_string_integer_add (temp_partition_sum, r1_upper_partition, r2_lower_partition);
          if (carry != NULL)
          {
            temp_partition_sum = packed_string_integer_add (temp_partition_sum, r1_upper_partition, r2_lower_partition);
            temp_packed_string_integer = packed_string_integer_add (temp_packed_string_integer, temp_partition_sum, carry);
            temp_partition_sum = packed_string_integer_release_memory (temp_partition_sum);
            temp_partition_sum = packed_string_integer_copy_number (temp_partition_sum, temp_packed_string_integer);
            temp_packed_string_integer = packed_string_integer_release_memory (temp_packed_string_integer);
            carry = packed_string_integer_component_release_memory (carry);
          }
          if (temp_partition_sum != NULL)
          {
            if (temp_partition_sum->left_of_decimal != NULL)
            {
              i = 0;
              state = 0;
              number_of_digits_appended = 0;
              temp_num = temp_partition_sum->left_of_decimal->first_number_block;
              while ((temp_num != NULL) && (number_of_digits_appended < number_of_digits))
              {
                if (temp_num->highest_digit_position < MAX_PACKED_NUMBER_BLOCK_SIZE)
                {
                  i = 0;
                  while ((i < temp_num->highest_digit_position) && (number_of_digits_appended < number_of_digits))
                  {
                    packed_byte = temp_num->packed_number_block[i];
                    switch (state)
                    {
                      case 0:
                        nibble_low  = packed_byte & 0x0f;
                        product = packed_string_integer_append_one_digit (product, nibble_low);
                        number_of_digits_appended++;
                        state = 1;
                      break;
                      case 1:
                        nibble_high = (packed_byte & 0xf0) >> 4;
                        product = packed_string_integer_append_one_digit (product, nibble_high);
                        number_of_digits_appended++;
                        state = 0;
                        i++;
                      break;
                      default:
                        printf ("Internal error occurred. Exiting now.\n");
                        exit (EXIT_FAILURE);
                      break;
                    }
                  }
                  done = FALSE;
                  while ((i == temp_num->highest_digit_position) && (number_of_digits_appended < number_of_digits) && (!done))
                  {
                    packed_byte = temp_num->packed_number_block[i];
                    switch (state)
                    {
                      case 0:
                        nibble_low  = packed_byte & 0x0f;
                        product = packed_string_integer_append_one_digit (product, nibble_low);
                        number_of_digits_appended++;
                        if (temp_num->highest_nibble_position == lo)
                        {
                          done = TRUE;
                          i++;
                        }
                        else
                        {
                          state = 1;
                        }
                      break;
                      case 1:
                        if (temp_num->highest_nibble_position == hi)
                        {
                          nibble_high = (packed_byte & 0xf0) >> 4;
                          product = packed_string_integer_append_one_digit (product, nibble_high);
                          number_of_digits_appended++;
                          state = 0;
                          i++;
                        }
                        else
                        {
                          done = TRUE;
                        }
                      break;
                      default:
                        printf ("Internal error occurred. Exiting now.\n");
                        exit (EXIT_FAILURE);
                      break;
                    }
                  }
                }
                else
                {
                  printf ("Internal error occurred. Exiting now.\n");
                  exit (EXIT_FAILURE);
                }
                if (i > temp_num->highest_digit_position)
                {
                  i = 0;
                  temp_num = temp_num->next_number_block;
                }
              } 
// ********************************************************************************************
// * Now copy over any reamining digits. These remaining digits represent the carry (if any). *
// ********************************************************************************************
              i2 = i;
              while (temp_num != NULL)
              {
                if (temp_num->highest_digit_position < MAX_PACKED_NUMBER_BLOCK_SIZE)
                {
                  i = i2;
                  while (i < temp_num->highest_digit_position)
                  {
                    packed_byte = temp_num->packed_number_block[i];
                    switch (state)
                    {
                      case 0:
                        nibble_low  = packed_byte & 0x0f;
                        carry = packed_string_integer_append_one_digit (carry, nibble_low);
                        state = 1;
                      break;
                      case 1:
                        nibble_high = (packed_byte & 0xf0) >> 4;
                        carry = packed_string_integer_append_one_digit (carry, nibble_high);
                        state = 0;
                        i++;
                      break;
                      default:
                        printf ("Internal error occurred. Exiting now.\n");
                        exit (EXIT_FAILURE);
                      break;
                    }
                  }
                  done = FALSE;
                  while ((i == temp_num->highest_digit_position) && (!done))
                  {
                    packed_byte = temp_num->packed_number_block[i];
                    switch (state)
                    {
                      case 0:
                        nibble_low  = packed_byte & 0x0f;
                        carry = packed_string_integer_append_one_digit (carry, nibble_low);
                        if (temp_num->highest_nibble_position == lo)
                        {
                          i++;
                          done = TRUE;
                        }
                        else
                        {
                          state = 1;
                        }
                      break;
                      case 1:
                        if (temp_num->highest_nibble_position == hi)
                        {
                          nibble_high = (packed_byte & 0xf0) >> 4;
                          carry = packed_string_integer_append_one_digit (carry, nibble_high);
                          state = 0;
                          i++;
                        }
                        else
                        {
                          done = TRUE;
                        }
                      break;
                      default:
                        printf ("Internal error occurred. Exiting now.\n");
                        exit (EXIT_FAILURE);
                      break;
                    }
                  }
                }
                else
                {
                  printf ("Internal error occurred. Exiting now.\n");
                  exit (EXIT_FAILURE);
                }
                if (i > temp_num->highest_digit_position)
                {
                  temp_num = temp_num->next_number_block;
                  i = 0;
                  i2 = 0;
                }
              } 
              if (carry != NULL)
              {
                carry = packed_string_integer_set_sign (carry, positive);
              }
            }   
            temp_partition_sum = packed_string_integer_release_memory (temp_partition_sum);
          }
        }
// ************************************************************************************************************************************************
// * RECOMPOSITION Step 8: add r2_upper_partion and r3_lower_partion. Then copy NUMBER_OF_DIGITS digits from the resultant sum into the product. * 
// ************************************************************************************************************************************************
        if ((r2_upper_partition != NULL) && (r3_lower_partition != NULL))
        {
          temp_partition_sum = packed_string_integer_add (temp_partition_sum, r2_upper_partition, r3_lower_partition);
          if (carry != NULL)
          {
            temp_partition_sum = packed_string_integer_add (temp_partition_sum, r2_upper_partition, r3_lower_partition);
            temp_packed_string_integer = packed_string_integer_add (temp_packed_string_integer, temp_partition_sum, carry);
            temp_partition_sum = packed_string_integer_release_memory (temp_partition_sum);
            temp_partition_sum = packed_string_integer_copy_number (temp_partition_sum, temp_packed_string_integer);
            temp_packed_string_integer = packed_string_integer_release_memory (temp_packed_string_integer);
            carry = packed_string_integer_component_release_memory (carry);
          }
          if (temp_partition_sum != NULL)
          {
            if (temp_partition_sum->left_of_decimal != NULL)
            {
              i = 0;
              state = 0;
              number_of_digits_appended = 0;
              temp_num = temp_partition_sum->left_of_decimal->first_number_block;
              while ((temp_num != NULL) && (number_of_digits_appended < number_of_digits))
              {
                if (temp_num->highest_digit_position < MAX_PACKED_NUMBER_BLOCK_SIZE)
                {
                  i = 0;
                  while ((i < temp_num->highest_digit_position) && (number_of_digits_appended < number_of_digits))
                  {
                    packed_byte = temp_num->packed_number_block[i];
                    switch (state)
                    {
                      case 0:
                        nibble_low  = packed_byte & 0x0f;
                        product = packed_string_integer_append_one_digit (product, nibble_low);
                        number_of_digits_appended++;
                        state = 1;
                      break;
                      case 1:
                        nibble_high = (packed_byte & 0xf0) >> 4;
                        product = packed_string_integer_append_one_digit (product, nibble_high);
                        number_of_digits_appended++;
                        state = 0;
                        i++;
                      break;
                      default:
                        printf ("Internal error occurred. Exiting now.\n");
                        exit (EXIT_FAILURE);
                      break;
                    }
                  }
                  done = FALSE;
                  while ((i == temp_num->highest_digit_position) && (number_of_digits_appended < number_of_digits) && (!done))
                  {
                    packed_byte = temp_num->packed_number_block[i];
                    switch (state)
                    {
                      case 0:
                        nibble_low  = packed_byte & 0x0f;
                        product = packed_string_integer_append_one_digit (product, nibble_low);
                        number_of_digits_appended++;
                        if (temp_num->highest_nibble_position == lo)
                        {
                          done = TRUE;
                          i++;
                        }
                        else
                        {
                          state = 1;
                        }
                      break;
                      case 1:
                        if (temp_num->highest_nibble_position == hi)
                        {
                          nibble_high = (packed_byte & 0xf0) >> 4;
                          product = packed_string_integer_append_one_digit (product, nibble_high);
                          number_of_digits_appended++;
                          state = 0;
                          i++;
                        }
                        else
                        {
                          done = TRUE;
                        }
                      break;
                      default:
                        printf ("Internal error occurred. Exiting now.\n");
                        exit (EXIT_FAILURE);
                      break;
                    }
                  }
                }
                else
                {
                  printf ("Internal error occurred. Exiting now.\n");
                  exit (EXIT_FAILURE);
                }
                if (i > temp_num->highest_digit_position)
                {
                  i = 0;
                  temp_num = temp_num->next_number_block;
                }
              } 
// ********************************************************************************************
// * Now copy over any reamining digits. These remaining digits represent the carry (if any). *
// ********************************************************************************************
              i2 = i;
              while (temp_num != NULL)
              {
                if (temp_num->highest_digit_position < MAX_PACKED_NUMBER_BLOCK_SIZE)
                {
                  i = i2;
                  while (i < temp_num->highest_digit_position)
                  {
                    packed_byte = temp_num->packed_number_block[i];
                    switch (state)
                    {
                      case 0:
                        nibble_low  = packed_byte & 0x0f;
                        carry = packed_string_integer_append_one_digit (carry, nibble_low);
                        state = 1;
                      break;
                      case 1:
                        nibble_high = (packed_byte & 0xf0) >> 4;
                        carry = packed_string_integer_append_one_digit (carry, nibble_high);
                        state = 0;
                        i++;
                      break;
                      default:
                        printf ("Internal error occurred. Exiting now.\n");
                        exit (EXIT_FAILURE);
                      break;
                    }
                  }
                  done = FALSE;
                  while ((i == temp_num->highest_digit_position) && (!done))
                  {
                    packed_byte = temp_num->packed_number_block[i];
                    switch (state)
                    {
                      case 0:
                        nibble_low  = packed_byte & 0x0f;
                        carry = packed_string_integer_append_one_digit (carry, nibble_low);
                        if (temp_num->highest_nibble_position == lo)
                        {
                          i++;
                          done = TRUE;
                        }
                        else
                        {
                          state = 1;
                        }
                      break;
                      case 1:
                        if (temp_num->highest_nibble_position == hi)
                        {
                          nibble_high = (packed_byte & 0xf0) >> 4;
                          carry = packed_string_integer_append_one_digit (carry, nibble_high);
                          state = 0;
                          i++;
                        }
                        else
                        {
                          done = TRUE;
                        }
                      break;
                      default:
                        printf ("Internal error occurred. Exiting now.\n");
                        exit (EXIT_FAILURE);
                      break;
                    }
                  }
                }
                else
                {
                  printf ("Internal error occurred. Exiting now.\n");
                  exit (EXIT_FAILURE);
                }
                if (i > temp_num->highest_digit_position)
                {
                  temp_num = temp_num->next_number_block;
                  i = 0;
                  i2 = 0;
                }
              } 
              if (carry != NULL)
              {
                carry = packed_string_integer_set_sign (carry, positive);
              }
            }   
            temp_partition_sum = packed_string_integer_release_memory (temp_partition_sum);
          }
        }
// ************************************************************************************************************************************************
// * RECOMPOSITION Step 9: add r3_upper_partion and r4_lower_partion. Then copy NUMBER_OF_DIGITS digits from the resultant sum into the product. * 
// ************************************************************************************************************************************************
        if ((r3_upper_partition != NULL) && (r4_lower_partition != NULL))
        {
          temp_partition_sum = packed_string_integer_add (temp_partition_sum, r3_upper_partition, r4_lower_partition);
          if (carry != NULL)
          {
            temp_partition_sum = packed_string_integer_add (temp_partition_sum, r3_upper_partition, r4_lower_partition);
            temp_packed_string_integer = packed_string_integer_add (temp_packed_string_integer, temp_partition_sum, carry);
            temp_partition_sum = packed_string_integer_release_memory (temp_partition_sum);
            temp_partition_sum = packed_string_integer_copy_number (temp_partition_sum, temp_packed_string_integer);
            temp_packed_string_integer = packed_string_integer_release_memory (temp_packed_string_integer);
            carry = packed_string_integer_component_release_memory (carry);
          }
          if (temp_partition_sum != NULL)
          {
            if (temp_partition_sum->left_of_decimal != NULL)
            {
              i = 0;
              state = 0;
              number_of_digits_appended = 0;
              temp_num = temp_partition_sum->left_of_decimal->first_number_block;
              while ((temp_num != NULL) && (number_of_digits_appended < number_of_digits))
              {
                if (temp_num->highest_digit_position < MAX_PACKED_NUMBER_BLOCK_SIZE)
                {
                  i = 0;
                  while ((i < temp_num->highest_digit_position) && (number_of_digits_appended < number_of_digits))
                  {
                    packed_byte = temp_num->packed_number_block[i];
                    switch (state)
                    {
                      case 0:
                        nibble_low  = packed_byte & 0x0f;
                        product = packed_string_integer_append_one_digit (product, nibble_low);
                        number_of_digits_appended++;
                        state = 1;
                      break;
                      case 1:
                        nibble_high = (packed_byte & 0xf0) >> 4;
                        product = packed_string_integer_append_one_digit (product, nibble_high);
                        number_of_digits_appended++;
                        state = 0;
                        i++;
                      break;
                      default:
                        printf ("Internal error occurred. Exiting now.\n");
                        exit (EXIT_FAILURE);
                      break;
                    }
                  }
                  done = FALSE;
                  while ((i == temp_num->highest_digit_position) && (number_of_digits_appended < number_of_digits) && (!done))
                  {
                    packed_byte = temp_num->packed_number_block[i];
                    switch (state)
                    {
                      case 0:
                        nibble_low  = packed_byte & 0x0f;
                        product = packed_string_integer_append_one_digit (product, nibble_low);
                        number_of_digits_appended++;
                        if (temp_num->highest_nibble_position == lo)
                        {
                          done = TRUE;
                          i++;
                        }
                        else
                        {
                          state = 1;
                        }
                      break;
                      case 1:
                        if (temp_num->highest_nibble_position == hi)
                        {
                          nibble_high = (packed_byte & 0xf0) >> 4;
                          product = packed_string_integer_append_one_digit (product, nibble_high);
                          number_of_digits_appended++;
                          state = 0;
                          i++;
                        }
                        else
                        {
                          done = TRUE;
                        }
                      break;
                      default:
                        printf ("Internal error occurred. Exiting now.\n");
                        exit (EXIT_FAILURE);
                      break;
                    }
                  }
                }
                else
                {
                  printf ("Internal error occurred. Exiting now.\n");
                  exit (EXIT_FAILURE);
                }
                if (i > temp_num->highest_digit_position)
                {
                  i = 0;
                  temp_num = temp_num->next_number_block;
                }
              } 
// ********************************************************************************************
// * Now copy over any reamining digits. These remaining digits represent the carry (if any). *
// ********************************************************************************************
              i2 = i;
              while (temp_num != NULL)
              {
                if (temp_num->highest_digit_position < MAX_PACKED_NUMBER_BLOCK_SIZE)
                {
                  i = i2;
                  while (i < temp_num->highest_digit_position)
                  {
                    packed_byte = temp_num->packed_number_block[i];
                    switch (state)
                    {
                      case 0:
                        nibble_low  = packed_byte & 0x0f;
                        carry = packed_string_integer_append_one_digit (carry, nibble_low);
                        state = 1;
                      break;
                      case 1:
                        nibble_high = (packed_byte & 0xf0) >> 4;
                        carry = packed_string_integer_append_one_digit (carry, nibble_high);
                        state = 0;
                        i++;
                      break;
                      default:
                        printf ("Internal error occurred. Exiting now.\n");
                        exit (EXIT_FAILURE);
                      break;
                    }
                  }
                  done = FALSE;
                  while ((i == temp_num->highest_digit_position) && (!done))
                  {
                    packed_byte = temp_num->packed_number_block[i];
                    switch (state)
                    {
                      case 0:
                        nibble_low  = packed_byte & 0x0f;
                        carry = packed_string_integer_append_one_digit (carry, nibble_low);
                        if (temp_num->highest_nibble_position == lo)
                        {
                          i++;
                          done = TRUE;
                        }
                        else
                        {
                          state = 1;
                        }
                      break;
                      case 1:
                        if (temp_num->highest_nibble_position == hi)
                        {
                          nibble_high = (packed_byte & 0xf0) >> 4;
                          carry = packed_string_integer_append_one_digit (carry, nibble_high);
                          state = 0;
                          i++;
                        }
                        else
                        {
                          done = TRUE;
                        }
                      break;
                      default:
                        printf ("Internal error occurred. Exiting now.\n");
                        exit (EXIT_FAILURE);
                      break;
                    }
                  }
                }
                else
                {
                  printf ("Internal error occurred. Exiting now.\n");
                  exit (EXIT_FAILURE);
                }
                if (i > temp_num->highest_digit_position)
                {
                  temp_num = temp_num->next_number_block;
                  i = 0;
                  i2 = 0;
                }
              } 
              if (carry != NULL)
              {
                carry = packed_string_integer_set_sign (carry, positive);
              }
            }   
            temp_partition_sum = packed_string_integer_release_memory (temp_partition_sum);
      
          }
        }
// ****************************************************************************************************************************************
// * RECOMPOSITION Step 10: add r4_upper_partion and carry (if any). Then copy ALL OF THE DIGITS from the resultant sum into the product. * 
// ****************************************************************************************************************************************
        if (r4_upper_partition != NULL)
        {
          if (carry != NULL)
          {
            temp_partition_sum = packed_string_integer_add (temp_partition_sum, r4_upper_partition, carry);
            carry = packed_string_integer_component_release_memory (carry);
          }
          else
          {
            temp_partition_sum = packed_string_integer_copy_number (temp_partition_sum, r4_upper_partition);
          }
          if (temp_partition_sum != NULL)
          {
            if (temp_partition_sum->left_of_decimal != NULL)
            {
              state = 0;
              temp_num = temp_partition_sum->left_of_decimal->first_number_block;
              while (temp_num != NULL) 
              {
                if (temp_num->highest_digit_position < MAX_PACKED_NUMBER_BLOCK_SIZE)
                {
                  i = 0;
                  while (i < temp_num->highest_digit_position)
                  {
                    packed_byte = temp_num->packed_number_block[i];
                    switch (state)
                    {
                      case 0:
                        nibble_low  = packed_byte & 0x0f;
                        product = packed_string_integer_append_one_digit (product, nibble_low);
                        state = 1;
                      break;
                      case 1:
                        nibble_high = (packed_byte & 0xf0) >> 4;
                        product = packed_string_integer_append_one_digit (product, nibble_high);
                        state = 0;
                        i++;
                      break;
                      default:
                        printf ("Internal error occurred. Exiting now.\n");
                        exit (EXIT_FAILURE);
                      break;
                    }
                  }
                  done = FALSE;
                  while ((i == temp_num->highest_digit_position) && (!done))
                  {
                    packed_byte = temp_num->packed_number_block[i];
                    switch (state)
                    {
                      case 0:
                        nibble_low  = packed_byte & 0x0f;
                        product = packed_string_integer_append_one_digit (product, nibble_low);
                        if (temp_num->highest_nibble_position == lo)
                        {
                          done = TRUE;
                          i++;
                        }
                        else
                        {
                          state = 1;
                        }
                      break;
                      case 1:
                        if (temp_num->highest_nibble_position == hi)
                        {
                          nibble_high = (packed_byte & 0xf0) >> 4;
                          product = packed_string_integer_append_one_digit (product, nibble_high);
                          state = 0;
                          i++;
                        }
                        else
                        {
                          done = TRUE;
                        }
                      break;
                      default:
                        printf ("Internal error occurred. Exiting now.\n");
                        exit (EXIT_FAILURE);
                      break;
                    }
                  }
                }
                else
                {
                  printf ("Internal error occurred. Exiting now.\n");
                  exit (EXIT_FAILURE);
                }
                if (i > temp_num->highest_digit_position)
                {
                  i = 0;
                  temp_num = temp_num->next_number_block;
                }
              } 
            }   
            temp_partition_sum = packed_string_integer_release_memory (temp_partition_sum);
          }
        }
      }
    }
  }   
// **************************************************
// * Release all temporary variables and constants. *
// **************************************************
  if (constant_two != NULL)
  {
    constant_two = packed_string_integer_release_memory (constant_two);
  }
  if (constant_three != NULL)
  {
    constant_three = packed_string_integer_release_memory (constant_three);
  }
  if (m0 != NULL)
  {
    m0 = packed_string_integer_release_memory (m0);
  }
  if (m1 != NULL)
  {
    m1 = packed_string_integer_release_memory (m1);
  }
  if (m2 != NULL)
  {
    m2 = packed_string_integer_release_memory (m2);
  }
  if (n0 != NULL)
  {
    n0 = packed_string_integer_release_memory (n0);
  }
  if (n1 != NULL)
  {
    n1 = packed_string_integer_release_memory (n1);
  }
  if (n2 != NULL)
  {
    n2 = packed_string_integer_release_memory (n2);
  }
  if (p0 != NULL)
  {
    p0 = packed_string_integer_release_memory (p0);
  }
  if (p_of_zero != NULL)
  {
    p_of_zero = packed_string_integer_release_memory (p_of_zero);
  }
  if (p_of_one != NULL)
  {
    p_of_one = packed_string_integer_release_memory (p_of_one);
  }
  if (p_of_minus_one != NULL)
  {
    p_of_minus_one = packed_string_integer_release_memory (p_of_minus_one);
  }
  if (p_of_minus_two != NULL)
  {
    p_of_minus_two = packed_string_integer_release_memory (p_of_minus_two);
  }
  if (pinf != NULL)
  {
    pinf = packed_string_integer_release_memory (pinf);
  }
  if (q0 != NULL)
  {
    q0 = packed_string_integer_release_memory (q0);
  }
  if (q_of_zero != NULL)
  {
    q_of_zero = packed_string_integer_release_memory (q_of_zero);
  }
  if (q_of_one != NULL)
  {
    q_of_one = packed_string_integer_release_memory (q_of_one);
  }
  if (q_of_minus_one != NULL)
  {
    q_of_minus_one = packed_string_integer_release_memory (q_of_minus_one);
  }
  if (q_of_minus_two != NULL)
  {
    q_of_minus_two = packed_string_integer_release_memory (q_of_minus_two);
  }
  if (qinf != NULL)
  {
    qinf = packed_string_integer_release_memory (qinf);
  }
  if (r0 != NULL)
  {
    r0 = packed_string_integer_release_memory (r0);
  }
  if (r_of_zero != NULL)
  {
    r_of_zero = packed_string_integer_release_memory (r_of_zero);
  }
  if (r_of_one != NULL)
  {
    r_of_one = packed_string_integer_release_memory (r_of_one);
  }
  if (r_of_minus_one != NULL)
  {
    r_of_minus_one = packed_string_integer_release_memory (r_of_minus_one);
  }
  if (r_of_minus_two != NULL)
  {
    r_of_minus_two = packed_string_integer_release_memory (r_of_minus_two);
  }
  if (rinf != NULL)
  {
    rinf = packed_string_integer_release_memory (rinf);
  }
  if (r1 != NULL)
  {
    r1 = packed_string_integer_release_memory (r1);
  }
  if (r2 != NULL)
  {
    r2 = packed_string_integer_release_memory (r2);
  }
  if (r3 != NULL)
  {
    r3 = packed_string_integer_release_memory (r3);
  }
  if (r4 != NULL)
  {
    r4 = packed_string_integer_release_memory (r4);
  }
  if (r0_upper_partition != NULL)
  {
    r0_upper_partition = packed_string_integer_release_memory (r0_upper_partition);
  }
  if (r1_lower_partition != NULL)
  {
    r1_lower_partition = packed_string_integer_release_memory (r1_lower_partition);
  }
  if (r1_upper_partition != NULL)
  {
    r1_upper_partition = packed_string_integer_release_memory (r1_upper_partition);
  }
  if (r2_lower_partition != NULL)
  {
    r2_lower_partition = packed_string_integer_release_memory (r2_lower_partition);
  }
  if (r2_upper_partition != NULL)
  {
    r2_upper_partition = packed_string_integer_release_memory (r2_upper_partition);
  }
  if (r3_lower_partition != NULL)
  {
    r3_lower_partition = packed_string_integer_release_memory (r3_lower_partition);
  }
  if (r3_upper_partition != NULL)
  {
    r3_upper_partition = packed_string_integer_release_memory (r3_upper_partition);
  }
  if (r4_lower_partition != NULL)
  {
    r4_lower_partition = packed_string_integer_release_memory (r4_lower_partition);
  }
  if (r4_upper_partition != NULL)
  {
    r4_upper_partition = packed_string_integer_release_memory (r4_upper_partition);
  }
  if (temp_partition_sum != NULL)
  {
    temp_partition_sum = packed_string_integer_release_memory (temp_partition_sum);
  }
  if (temp_partition_sum_with_carry != NULL)
  {
    temp_partition_sum_with_carry = packed_string_integer_release_memory (temp_partition_sum_with_carry);
  }
  if (temp_packed_string_integer != NULL)
  {
    temp_packed_string_integer = packed_string_integer_release_memory (temp_packed_string_integer);
  }
  if (temp_packed_string_integer2 != NULL)
  {
    temp_packed_string_integer2 = packed_string_integer_release_memory (temp_packed_string_integer2);
  }
  if (carry != NULL)
  {
    carry = packed_string_integer_release_memory (carry);
  }
  return product;
}




// **************************************************************************************
// * packed_string_integer_multiply                                                     *
// *                                                                                    *
// * Call this subroutine to multiply two string-based integers together.               *
// * Inputs: num1 (packed string-based integer) and num2 (packed string-based integer). *
// * Output: A string-based integer representing the product of num1 and num2.          *
// **************************************************************************************
psint * packed_string_integer_multiply (psint *product, psint *num1, psint *num2)
{
  long long int num1_number_of_digits, num2_number_of_digits;
  int greater_number;

// *************************************************************************
// * Release any previously used memory otherwise we'd have a memory leak. *
// *************************************************************************
  if (product != NULL)
  {
    product = packed_string_integer_component_release_memory (product);
  }
  if ((num1 != NULL) && (num2 != NULL))
  {
    num1_number_of_digits = count_num_digits_in_packed_string_integer (num1);
    num2_number_of_digits = count_num_digits_in_packed_string_integer (num2);
    greater_number = packed_string_integer_determine_absolute_value_larger_of_two_integers (num1, num2);
    switch (greater_number)
    {
      case 1: // num1 > num2
        switch (num1->sign)
        {
          case positive:
            switch (num2->sign)
            {
              case positive: // num1 is positive, num2 is positive, num1 * num2 = positive sign. num1 > num2
                if ((num1_number_of_digits > NUM_DIGITS_THRESHOLD_FOR_USING_TOOM3) && (num2_number_of_digits > NUM_DIGITS_THRESHOLD_FOR_USING_TOOM3))
                {
                  product = _packed_string_integer_multiply_with_toom3 (product, num1, num2);
                  if (product == NULL)
                  {
                    product = _packed_string_integer_multiply (product, num1, num2);
                  }
                }
                else
                {
                  product = _packed_string_integer_multiply (product, num1, num2);
                }
                product = packed_string_integer_set_sign (product, positive);
              break;
              case zero: // Anything multiplied by zero is zero. Rather than compute a value, simply create a zero result.
                product = packed_string_integer_initialize_to_zero (product);
              break;
              case negative:
                if ((num1_number_of_digits > NUM_DIGITS_THRESHOLD_FOR_USING_TOOM3) && (num2_number_of_digits > NUM_DIGITS_THRESHOLD_FOR_USING_TOOM3))
                {
                  product = _packed_string_integer_multiply_with_toom3 (product, num1, num2);
                  if (product == NULL)
                  {
                    product = _packed_string_integer_multiply (product, num1, num2);
                  }
                }
                else
                {
                  product = _packed_string_integer_multiply (product, num1, num2);
                }
                product = packed_string_integer_set_sign (product, negative);
              break;
              case undefined:
              break;
              default:
              break;
            }
          break;
          case zero: // Anything multiplied by zero is zero. Rather than compute a value, simply create a zero result.
            product = packed_string_integer_initialize_to_zero (product);
          break;
          case negative:
            switch (num2->sign)
            {
              case positive: // num1 is negative, num2 is positive. num1 * num2 = negative sign.
                if ((num1_number_of_digits > NUM_DIGITS_THRESHOLD_FOR_USING_TOOM3) && (num2_number_of_digits > NUM_DIGITS_THRESHOLD_FOR_USING_TOOM3))
                {
                  product = _packed_string_integer_multiply_with_toom3 (product, num1, num2);
                  if (product == NULL)
                  {
                    product = _packed_string_integer_multiply (product, num1, num2);
                  }
                }
                else
                {
                  product = _packed_string_integer_multiply (product, num1, num2);
                }
                product = packed_string_integer_set_sign (product, negative);
              break;
              case zero: // Anything multiplied by zero is zero. Rather than compute a value, simply create a zero result.
                product = packed_string_integer_initialize_to_zero (product);
              break;
              case negative: // num1 is negative, num2 is negative. num1 * num2 = positive sign.
                if ((num1_number_of_digits > NUM_DIGITS_THRESHOLD_FOR_USING_TOOM3) && (num2_number_of_digits > NUM_DIGITS_THRESHOLD_FOR_USING_TOOM3))
                {
                  product = _packed_string_integer_multiply_with_toom3 (product, num1, num2);
                  if (product == NULL)
                  {
                    product = _packed_string_integer_multiply (product, num1, num2);
                  }
                }
                else
                {
                  product = _packed_string_integer_multiply (product, num1, num2);
                }
                product = packed_string_integer_set_sign (product, positive);
              break;
              case undefined:
              break;
              default:
              break;
            }
          break;
          default:
          break;
        }
      break;
      case 0: // num1 == num2
        switch (num1->sign)
        {
          case positive:
            switch (num2->sign)
            {
              case positive: // num1 == num2: num1 is positive, num2 is positive, num1 * num2 = positive sign. num1 > num2
                if ((num1_number_of_digits > NUM_DIGITS_THRESHOLD_FOR_USING_TOOM3) && (num2_number_of_digits > NUM_DIGITS_THRESHOLD_FOR_USING_TOOM3))
                {
                  product = _packed_string_integer_multiply_with_toom3 (product, num1, num2);
                  if (product == NULL)
                  {
                    product = _packed_string_integer_multiply (product, num1, num2);
                  }
                }
                else
                {
                  product = _packed_string_integer_multiply (product, num1, num2);
                }
                product = packed_string_integer_set_sign (product, positive);
              break;
              case zero: // Anything multiplied by zero is zero. Rather than compute a value, simply create a zero result.
                product = packed_string_integer_initialize_to_zero (product);
              break;
              case negative:
                if ((num1_number_of_digits > NUM_DIGITS_THRESHOLD_FOR_USING_TOOM3) && (num2_number_of_digits > NUM_DIGITS_THRESHOLD_FOR_USING_TOOM3))
                {
                  product = _packed_string_integer_multiply_with_toom3 (product, num1, num2);
                  if (product == NULL)
                  {
                    product = _packed_string_integer_multiply (product, num1, num2);
                  }
                }
                else
                {
                  product = _packed_string_integer_multiply (product, num1, num2);
                }
                product = packed_string_integer_set_sign (product, negative);
              break;
              case undefined:
              break;
              default:
              break;
            }
          break;
          case zero: // num1 == num2: Anything multiplied by zero is zero. Rather than compute a value, simply create a zero result.
            product = packed_string_integer_initialize_to_zero (product);
          break;
          case negative:
            switch (num2->sign)
            {
              case positive: // num1 == num2: num1 is negative, num2 is positive. num1 * num2 = negative sign.
                if ((num1_number_of_digits > NUM_DIGITS_THRESHOLD_FOR_USING_TOOM3) && (num2_number_of_digits > NUM_DIGITS_THRESHOLD_FOR_USING_TOOM3))
                {
                  product = _packed_string_integer_multiply_with_toom3 (product, num1, num2);
                  if (product == NULL)
                  {
                    product = _packed_string_integer_multiply (product, num1, num2);
                  }
                }
                else
                {
                  product = _packed_string_integer_multiply (product, num1, num2);
                }
                product = packed_string_integer_set_sign (product, negative);
              break;
              case zero: // num1 == num2: Anything multiplied by zero is zero. Rather than compute a value, simply create a zero result.
                product = packed_string_integer_initialize_to_zero (product);
              break;
              case negative: // num1 == num2: num1 is negative, num2 is negative. num1 * num2 = positive sign.
                if ((num1_number_of_digits > NUM_DIGITS_THRESHOLD_FOR_USING_TOOM3) && (num2_number_of_digits > NUM_DIGITS_THRESHOLD_FOR_USING_TOOM3))
                {
                  product = _packed_string_integer_multiply_with_toom3 (product, num1, num2);
                  if (product == NULL)
                  {
                    product = _packed_string_integer_multiply (product, num1, num2);
                  }
                }
                else
                {
                  product = _packed_string_integer_multiply (product, num1, num2);
                }
                product = packed_string_integer_set_sign (product, positive);
              break;
              case undefined:
              break;
              default:
              break;
            }
          break;
          default:
          break;
        }
      break;
      case -1: // num1 < num2
        switch (num1->sign)
        {
          case positive:
            switch (num2->sign)
            {
              case positive: // num1 < num2: num1 is positive, num2 is positive, num1 * num2 = positive sign
                if ((num1_number_of_digits > NUM_DIGITS_THRESHOLD_FOR_USING_TOOM3) && (num2_number_of_digits > NUM_DIGITS_THRESHOLD_FOR_USING_TOOM3))
                {
                  product = _packed_string_integer_multiply_with_toom3 (product, num2, num1);
                  if (product == NULL)
                  {
                    product = _packed_string_integer_multiply (product, num2, num1);
                  }
                }
                else
                {
                  product = _packed_string_integer_multiply (product, num2, num1);
                }
                product = packed_string_integer_set_sign (product, positive);
              break;
              case zero: // num1 < num2: Anything multiplied by zero is zero. Rather than compute a value, simply create a zero result.
                product = packed_string_integer_initialize_to_zero (product);
              break;
              case negative:
                if ((num1_number_of_digits > NUM_DIGITS_THRESHOLD_FOR_USING_TOOM3) && (num2_number_of_digits > NUM_DIGITS_THRESHOLD_FOR_USING_TOOM3))
                {
                  product = _packed_string_integer_multiply_with_toom3 (product, num2, num1);
                  if (product == NULL)
                  {
                    product = _packed_string_integer_multiply (product, num2, num1);
                  }
                }
                else
                {
                  product = _packed_string_integer_multiply (product, num2, num1);
                }
                product = packed_string_integer_set_sign (product, negative);
              break;
              case undefined:
              break;
              default:
              break;
            }
          break;
          case zero: // num1 < num2: Anything multiplied by zero is zero. Rather than compute a value, simply create a zero result.
            product = packed_string_integer_initialize_to_zero (product);
          break;
          case negative:
            switch (num2->sign)
            {
              case positive: // num1 < num2: num1 is negative, num2 is positive. num1 * num2 = negative sign.
                if ((num1_number_of_digits > NUM_DIGITS_THRESHOLD_FOR_USING_TOOM3) && (num2_number_of_digits > NUM_DIGITS_THRESHOLD_FOR_USING_TOOM3))
                {
                  product = _packed_string_integer_multiply_with_toom3 (product, num2, num1);
                  if (product == NULL)
                  {
                    product = _packed_string_integer_multiply (product, num2, num1);
                  }
                }
                else
                {
                  product = _packed_string_integer_multiply (product, num2, num1);
                }
                product = packed_string_integer_set_sign (product, negative);
              break;
              case zero: // num1 < num2: Anything multiplied by zero is zero. Rather than compute a value, simply create a zero result.
                product = packed_string_integer_initialize_to_zero (product);
              break;
              case negative: // num1 < num2: num1 is negative, num2 is negative. num1 * num2 = positive sign.
                if ((num1_number_of_digits > NUM_DIGITS_THRESHOLD_FOR_USING_TOOM3) && (num2_number_of_digits > NUM_DIGITS_THRESHOLD_FOR_USING_TOOM3))
                {
                  product = _packed_string_integer_multiply_with_toom3 (product, num2, num1);
                  if (product == NULL)
                  {
                    product = _packed_string_integer_multiply (product, num2, num1);
                  }
                }
                else
                {
                  product = _packed_string_integer_multiply (product, num2, num1);
                }
                product = packed_string_integer_set_sign (product, positive);
              break;
              case undefined:
              break;
              default:
              break;
            }
          break;
          default:
          break;
        }
      break;
      default:
      break;
    }
  }
  return product;
}  




// **************************************************************************************
// * packed_string_integer_multiply_traditional                                         *
// *                                                                                    *
// * Call this subroutine to multiply two string-based integers together.               *
// * Inputs: num1 (packed string-based integer) and num2 (packed string-based integer). *
// * Output: A string-based integer representing the product of num1 and num2.          *
// **************************************************************************************
psint * packed_string_integer_multiply_traditional (psint *product, psint *num1, psint *num2)
{
  int greater_number;

// *************************************************************************
// * Release any previously used memory otherwise we'd have a memory leak. *
// *************************************************************************
  if (product != NULL)
  {
    product = packed_string_integer_component_release_memory (product);
  }
  if ((num1 != NULL) && (num2 != NULL))
  {
    greater_number = packed_string_integer_determine_absolute_value_larger_of_two_integers (num1, num2);
    switch (greater_number)
    {
      case 1: // num1 > num2
        switch (num1->sign)
        {
          case positive:
            switch (num2->sign)
            {
              case positive: // num1 is positive, num2 is positive, num1 * num2 = positive sign. num1 > num2
                product = _packed_string_integer_multiply (product, num1, num2);
                product = packed_string_integer_set_sign (product, positive);
              break;
              case zero: // Anything multiplied by zero is zero. Rather than compute a value, simply create a zero result.
                product = packed_string_integer_initialize_to_zero (product);
              break;
              case negative:
                product = _packed_string_integer_multiply (product, num1, num2);
                product = packed_string_integer_set_sign (product, negative);
              break;
              case undefined:
              break;
              default:
              break;
            }
          break;
          case zero: // Anything multiplied by zero is zero. Rather than compute a value, simply create a zero result.
            product = packed_string_integer_initialize_to_zero (product);
          break;
          case negative:
            switch (num2->sign)
            {
              case positive: // num1 is negative, num2 is positive. num1 * num2 = negative sign.
                product = _packed_string_integer_multiply (product, num1, num2);
                product = packed_string_integer_set_sign (product, negative);
              break;
              case zero: // Anything multiplied by zero is zero. Rather than compute a value, simply create a zero result.
                product = packed_string_integer_initialize_to_zero (product);
              break;
              case negative: // num1 is negative, num2 is negative. num1 * num2 = positive sign.
                product = _packed_string_integer_multiply (product, num1, num2);
                product = packed_string_integer_set_sign (product, positive);
              break;
              case undefined:
              break;
              default:
              break;
            }
          break;
          default:
          break;
        }
      break;
      case 0: // num1 == num2
        switch (num1->sign)
        {
          case positive:
            switch (num2->sign)
            {
              case positive: // num1 == num2: num1 is positive, num2 is positive, num1 * num2 = positive sign. num1 > num2
                product = _packed_string_integer_multiply (product, num1, num2);
                product = packed_string_integer_set_sign (product, positive);
              break;
              case zero: // Anything multiplied by zero is zero. Rather than compute a value, simply create a zero result.
                product = packed_string_integer_initialize_to_zero (product);
              break;
              case negative:
                product = _packed_string_integer_multiply (product, num1, num2);
                product = packed_string_integer_set_sign (product, negative);
              break;
              case undefined:
              break;
              default:
              break;
            }
          break;
          case zero: // num1 == num2: Anything multiplied by zero is zero. Rather than compute a value, simply create a zero result.
            product = packed_string_integer_initialize_to_zero (product);
          break;
          case negative:
            switch (num2->sign)
            {
              case positive: // num1 == num2: num1 is negative, num2 is positive. num1 * num2 = negative sign.
                product = _packed_string_integer_multiply (product, num1, num2);
                product = packed_string_integer_set_sign (product, negative);
              break;
              case zero: // num1 == num2: Anything multiplied by zero is zero. Rather than compute a value, simply create a zero result.
                product = packed_string_integer_initialize_to_zero (product);
              break;
              case negative: // num1 == num2: num1 is negative, num2 is negative. num1 * num2 = positive sign.
                product = _packed_string_integer_multiply (product, num1, num2);
                product = packed_string_integer_set_sign (product, positive);
              break;
              case undefined:
              break;
              default:
              break;
            }
          break;
          default:
          break;
        }
      break;
      case -1: // num1 < num2
        switch (num1->sign)
        {
          case positive:
            switch (num2->sign)
            {
              case positive: // num1 < num2: num1 is positive, num2 is positive, num1 * num2 = positive sign
                product = _packed_string_integer_multiply (product, num2, num1);
                product = packed_string_integer_set_sign (product, positive);
              break;
              case zero: // num1 < num2: Anything multiplied by zero is zero. Rather than compute a value, simply create a zero result.
                product = packed_string_integer_initialize_to_zero (product);
              break;
              case negative:
                product = _packed_string_integer_multiply (product, num2, num1);
                product = packed_string_integer_set_sign (product, negative);
              break;
              case undefined:
              break;
              default:
              break;
            }
          break;
          case zero: // num1 < num2: Anything multiplied by zero is zero. Rather than compute a value, simply create a zero result.
            product = packed_string_integer_initialize_to_zero (product);
          break;
          case negative:
            switch (num2->sign)
            {
              case positive: // num1 < num2: num1 is negative, num2 is positive. num1 * num2 = negative sign.
                product = _packed_string_integer_multiply (product, num2, num1);
                product = packed_string_integer_set_sign (product, negative);
              break;
              case zero: // num1 < num2: Anything multiplied by zero is zero. Rather than compute a value, simply create a zero result.
                product = packed_string_integer_initialize_to_zero (product);
              break;
              case negative: // num1 < num2: num1 is negative, num2 is negative. num1 * num2 = positive sign.
                product = _packed_string_integer_multiply (product, num2, num1);
                product = packed_string_integer_set_sign (product, positive);
              break;
              case undefined:
              break;
              default:
              break;
            }
          break;
          default:
          break;
        }
      break;
      default:
      break;
    }
  }
  return product;
}




// *********************************************************************************************************
// * _packed_string_integer_divide_on_positive_integers_returning_quotient_and_remainder_high_performance  *
// *                                                                                                       *
// * This is a special, high-performance version internal subroutine that returns a linked-list containing *
// * two stringint elements: a quotient and a remainder.                                                   *
// *                                                                                                       *
// * NOTE: num1 and num2 must be positive integers before calling this internal subroutine.                *
// *********************************************************************************************************
psint_list_node * _packed_string_integer_divide_on_positive_integers_returning_quotient_and_remainder_high_performance (psint *num1, psint *num2)
{
  psint_list_node *stringint_list, *stringint_element_quotient, *stringint_element_remainder;
  psint *numerator, *denominator, *temp_denominator, *quotient, *remainder, *temp_quotient, *temp_numerator, *power_of_ten, *constant_1;
  long long int number_of_digits_in_numerator, number_of_digits_in_denominator, number_of_digits_difference;
  int done, greater_number;

  stringint_list   = NULL;
  numerator        = NULL;
  denominator      = NULL;
  temp_numerator   = NULL;
  temp_denominator = NULL;
  temp_quotient    = NULL;
  quotient         = NULL;
  remainder        = NULL;
  power_of_ten     = NULL;
  constant_1       = NULL;
  number_of_digits_in_numerator   = 0;
  number_of_digits_in_denominator = 0;

  if ((num1 != NULL) && (num2 != NULL))
  {
    if ((num1->left_of_decimal != NULL) && (num2->left_of_decimal != NULL))
    {
      constant_1  = packed_string_integer_set_value (constant_1, "1");
      numerator   = packed_string_integer_copy_number (numerator, num1);
      denominator = packed_string_integer_copy_number (denominator, num2);
      quotient    = packed_string_integer_initialize_to_zero (quotient);
      remainder   = packed_string_integer_copy_number (remainder, numerator);
    }
  }
  if ((numerator != NULL) && (denominator != NULL) && (constant_1 != NULL))
  {
    number_of_digits_in_numerator   = count_num_digits_in_packed_string_integer (numerator);
    number_of_digits_in_denominator = count_num_digits_in_packed_string_integer (denominator);
    //printf ("psint: numerator   = ");
    //packed_string_integer_display (numerator, 1);
    //printf ("\n");
    //printf ("psint: denominator = ");
    //packed_string_integer_display (denominator, 1);
    //printf ("\n");
    //printf ("psint: number_of_digits_in_numerator = %lld\n", number_of_digits_in_numerator);
    //printf ("psint: number_of_digits_in_denominator = %lld\n", number_of_digits_in_denominator);
    if (number_of_digits_in_numerator < number_of_digits_in_denominator)
    {
      remainder = packed_string_integer_copy_number (remainder, denominator);
    }
    else
    {
      done = FALSE;
      number_of_digits_difference = number_of_digits_in_numerator - number_of_digits_in_denominator;
      //printf ("psint: number_of_digits_difference = %lld\n", number_of_digits_difference);
      greater_number = packed_string_integer_determine_absolute_value_larger_of_two_integers (numerator, denominator);
      //printf ("psint: greater_number = %d (numerator vs. denominator)\n", greater_number);
      if (greater_number == -1)
      {
        done = TRUE;
      }
      while ((number_of_digits_difference >= 0) && (!done))
      {
        power_of_ten = packed_string_integer_component_release_memory (power_of_ten);
        power_of_ten = packed_string_integer_shift_digits_left (constant_1, number_of_digits_difference); // product = temp_product * 10^i 
        temp_denominator = packed_string_integer_shift_digits_left (denominator, number_of_digits_difference); // product = temp_product * 10^i 
        temp_denominator = packed_string_integer_set_sign (temp_denominator, positive);
        //printf ("psint: numerator        = ");
        //packed_string_integer_display (numerator, 1);
        //printf ("\n");
        //printf ("psint: temp_denominator = ");
        //packed_string_integer_display (temp_denominator, 1);
        //printf ("\n");
        //printf ("psint: power_of_ten = ");
        //packed_string_integer_display (power_of_ten, 1);
        //printf ("\n");
        greater_number = packed_string_integer_determine_absolute_value_larger_of_two_integers (numerator, temp_denominator);
        //printf ("psint: greater_number = %d (numerator vs. temp_denominator)\n", greater_number);
        while (((greater_number == 1) || (greater_number == 0)) && (!done))
        {
          temp_quotient = packed_string_integer_add (temp_quotient, quotient, power_of_ten);
          quotient      = packed_string_integer_component_release_memory (quotient);
          quotient      = packed_string_integer_copy_number (quotient, temp_quotient);
          temp_quotient = packed_string_integer_release_memory (temp_quotient);
          temp_numerator = packed_string_integer_subtract (temp_numerator, numerator, temp_denominator);
          numerator      = packed_string_integer_component_release_memory (numerator);
          numerator      = packed_string_integer_copy_number (numerator, temp_numerator);
          temp_numerator = packed_string_integer_release_memory (temp_numerator);
          greater_number = packed_string_integer_determine_absolute_value_larger_of_two_integers (numerator, temp_denominator);
          //printf ("psint: numerator = ");
          //packed_string_integer_display (numerator, 0);
          //printf ("\n");
          //printf ("psint: greater_number = %d (numerator vs. temp_denominator)\n", greater_number);
        }
        greater_number = packed_string_integer_determine_absolute_value_larger_of_two_integers (numerator, denominator);
        if (greater_number == -1)
        {
          done = TRUE;
        }
        number_of_digits_difference--;
      }
      if (remainder != NULL)
      {
        remainder = packed_string_integer_component_release_memory (remainder);
      }
      remainder = packed_string_integer_copy_number (remainder, numerator);
      //printf ("psint: quotient = ");
      //packed_string_integer_display (quotient, 1);
      //printf ("\n");
      //printf ("psint: remainder = ");
      //packed_string_integer_display (numerator, 1);
      //printf ("\n");
    }
  }
  if ((quotient != NULL) && (remainder != NULL))
  {
    stringint_element_remainder = (psint_list_node *) malloc(sizeof(psint_list_node));
    if (stringint_element_remainder != NULL)
    {
      stringint_element_remainder->element = remainder;
      stringint_element_remainder->next_element = NULL;
      stringint_element_quotient = (psint_list_node *) malloc(sizeof(psint_list_node));
      if (stringint_element_quotient != NULL)
      {
        stringint_element_quotient->element = quotient;
        stringint_element_quotient->next_element = stringint_element_remainder;
        stringint_list = stringint_element_quotient;
      }
      else
      {
        printf ("Error in _packed_string_integer_divide_on_positive_integers_returning_quotient_and_remainder_high_performance: malloc() failed. Exiting now.\n");
        exit (EXIT_FAILURE);
      }
    }
    else
    {
      printf ("Error in _packed_string_integer_divide_on_positive_integers_returning_quotient_and_remainder_high_performance: malloc() failed. Exiting now.\n");
      exit (EXIT_FAILURE);
    }
  }
  else
  {
    if (quotient != NULL)
    {
      quotient = packed_string_integer_release_memory (quotient);
    }
    if (remainder != NULL)
    {
      remainder = packed_string_integer_release_memory (remainder);
    }
  }
  if (constant_1 != NULL)
  {
    constant_1 = packed_string_integer_release_memory (constant_1);
  }
  if (power_of_ten != NULL)
  {
    power_of_ten = packed_string_integer_release_memory (power_of_ten);
  } 
  if (temp_numerator != NULL)
  {
    temp_numerator = packed_string_integer_release_memory (temp_numerator);
  }
  if (numerator != NULL)
  {
    numerator = packed_string_integer_release_memory (numerator);
  }
  if (temp_denominator != NULL)
  {
    temp_denominator = packed_string_integer_release_memory (temp_denominator);
  }
  if (denominator != NULL)
  {
    denominator = packed_string_integer_release_memory (denominator);
  }
  if (temp_quotient != NULL)
  {
    temp_quotient = packed_string_integer_release_memory (temp_quotient);
  }
  return stringint_list;
}




// ***************************************************************************************************
// * packed_string_integer_divide_returning_quotient_and_remainder                                   *
// *                                                                                                 *
// * This is the front-end for an internal subroutine.                                               *
// *                                                                                                 *
// * The front end portion checks for edge cases such as dividing by zero, numerator is zero, etc.   *
// *                                                                                                 *
// * Inputs: num1 (packed string-based integer) and num2 (packed string-based integer).              *
// * Output: a linked-list containing two string-based integer elements: a quotient and a remainder. *
// ***************************************************************************************************
psint_list_node * packed_string_integer_divide_returning_quotient_and_remainder (psint *num1, psint *num2)
{
  psint_list_node *quotient_and_remainder_list, *remainder_element, *quotient_element;
  psint *temp_num1, *temp_num2, *quotient, *remainder;
  int greater_number;

  temp_num1  = NULL;
  temp_num2  = NULL;
  quotient   = NULL;
  remainder  = NULL;
  remainder_element = NULL;
  quotient_element  = NULL;
  quotient_and_remainder_list = NULL;
  if ((num1 != NULL) && (num2 != NULL))
  {
    if (num1->sign == zero)
    {
      if ((num2->sign == positive) || (num2->sign == negative))
      {
        quotient = packed_string_integer_initialize_to_zero (quotient);
        remainder = packed_string_integer_initialize_to_zero (remainder);
      }
      else
      {
        if (num2->sign == zero)
        {
          quotient = packed_string_integer_initialize_to_undefined (quotient); 
          quotient = packed_string_integer_set_status_flag (quotient, DIVIDE_BY_ZERO);
          remainder = packed_string_integer_initialize_to_undefined (remainder); 
          remainder = packed_string_integer_set_status_flag (remainder, DIVIDE_BY_ZERO);
        }
        else
        {
          if (num2->sign == undefined)
          {
            quotient = packed_string_integer_initialize_to_undefined (quotient); 
            quotient = packed_string_integer_set_status_flag (quotient, INTERNAL_ERROR);
            remainder = packed_string_integer_initialize_to_undefined (remainder); 
            remainder = packed_string_integer_set_status_flag (remainder, INTERNAL_ERROR);
          }
        }
      }
    }
    else
    {
      if (num1->sign == positive)
      {
        if (num2->sign == positive)
        {
          if ((num1->left_of_decimal != NULL) && (num2->left_of_decimal != NULL))
          {
            greater_number = packed_string_integer_determine_absolute_value_larger_of_two_integers (num1, num2);
            if (greater_number == 0)
            {
              quotient = packed_string_integer_set_value (quotient, "1");
              quotient = packed_string_integer_set_status_flag (quotient, NONE);
              remainder = packed_string_integer_initialize_to_zero (remainder);
            }
            else
            {
              if (greater_number == -1)
              {
                quotient = packed_string_integer_initialize_to_zero (quotient);
                remainder = packed_string_integer_copy_number (remainder, num1);
              }
              else
              {
                if (greater_number == 1)
                {
                  greater_number = packed_string_integer_determine_absolute_value_number_greater_than_one (num2);
                  if (greater_number == 0)
                  {  
                    quotient = packed_string_integer_copy_number (quotient, num1);
                    quotient = packed_string_integer_set_status_flag (quotient, NONE);
                    remainder = packed_string_integer_initialize_to_zero (remainder);
                  }
                  else
                  {
                    quotient_and_remainder_list = _packed_string_integer_divide_on_positive_integers_returning_quotient_and_remainder_high_performance (num1, num2);
                  }
                }
                else
                {
                  if (greater_number == -2)
                  {
                    quotient = packed_string_integer_initialize_to_undefined (quotient); 
                    quotient = packed_string_integer_set_status_flag (quotient, INTERNAL_ERROR);
                    remainder = packed_string_integer_initialize_to_undefined (remainder); 
                    remainder = packed_string_integer_set_status_flag (remainder, INTERNAL_ERROR);
                  }
                }
              }
            }
          }
          else
          {
            quotient = packed_string_integer_initialize_to_undefined (quotient); 
            quotient = packed_string_integer_set_status_flag (quotient, INTERNAL_ERROR);
            remainder = packed_string_integer_initialize_to_undefined (remainder); 
            remainder = packed_string_integer_set_status_flag (remainder, INTERNAL_ERROR);
          }
        }
        else
        {
          if (num2->sign == negative)
          {
            if ((num1->left_of_decimal != NULL) && (num2->left_of_decimal != NULL))
            {
              greater_number = packed_string_integer_determine_absolute_value_larger_of_two_integers (num1, num2);
              if (greater_number == 0)
              {
                quotient = packed_string_integer_set_value (quotient, "1");
                quotient = packed_string_integer_set_sign (quotient, negative);
                quotient = packed_string_integer_set_status_flag (quotient, NONE);
                remainder = packed_string_integer_initialize_to_zero (remainder);
                remainder = packed_string_integer_set_status_flag (remainder, NONE);
              }
              else
              {
                if (greater_number == -1)
                {
                  quotient = packed_string_integer_initialize_to_zero (quotient);
                }
                else
                {
                  if (greater_number == 1)
                  {
                    greater_number = packed_string_integer_determine_absolute_value_number_greater_than_one (num2);
                    if (greater_number == 0)
                    {  
                      quotient = packed_string_integer_copy_number (quotient, num1);
                      quotient = packed_string_integer_set_status_flag (quotient, NONE);
                    }
                    else
                    {
                      temp_num2 = packed_string_integer_copy_number (temp_num2, num2);
                      temp_num2 = packed_string_integer_set_sign (temp_num2, positive);
                      quotient_and_remainder_list = _packed_string_integer_divide_on_positive_integers_returning_quotient_and_remainder_high_performance (num1, temp_num2);
                      if (quotient_and_remainder_list != NULL)
                      {
                        if (quotient_and_remainder_list->element != NULL)
                        {
                          quotient_and_remainder_list->element = packed_string_integer_set_sign (quotient_and_remainder_list->element, negative);
                        }
                      }
                    }
                  }
                  else
                  {
                    if (greater_number == -2)
                    {
                      quotient = packed_string_integer_initialize_to_undefined (quotient); 
                      quotient = packed_string_integer_set_status_flag (quotient, INTERNAL_ERROR);
                    }
                  }
                }
              }
            }
          }
          else
          {
            if (num2->sign == zero)
            {
              quotient = packed_string_integer_initialize_to_undefined (quotient); 
              quotient = packed_string_integer_set_status_flag (quotient, DIVIDE_BY_ZERO);
              remainder = packed_string_integer_initialize_to_undefined (remainder); 
              remainder = packed_string_integer_set_status_flag (remainder, DIVIDE_BY_ZERO);
            }
            else
            {
              if (num2->sign == undefined)
              {
                quotient = packed_string_integer_initialize_to_undefined (quotient); 
                quotient = packed_string_integer_set_status_flag (quotient, INTERNAL_ERROR);
                remainder = packed_string_integer_initialize_to_undefined (remainder); 
                remainder = packed_string_integer_set_status_flag (remainder, INTERNAL_ERROR);
              }
            }
          }
        }
      }
      else
      {
        if (num1->sign == negative)
        {
          if (num2->sign == positive)
          {
            if ((num1->left_of_decimal != NULL) && (num2->left_of_decimal != NULL))
            {
              greater_number = packed_string_integer_determine_absolute_value_larger_of_two_integers (num1, num2);
              if (greater_number == 0)
              {
                quotient = packed_string_integer_set_value (quotient, "-1");
                quotient = packed_string_integer_set_status_flag (quotient, NONE);
                remainder = packed_string_integer_initialize_to_zero (remainder);
              }
              else
              {
                if (greater_number == -1)
                {
                  quotient = packed_string_integer_initialize_to_zero (quotient);
                  remainder = packed_string_integer_copy_number (remainder, num1);
                }
                else
                {
                  if (greater_number == 1)
                  {
                    greater_number = packed_string_integer_determine_absolute_value_number_greater_than_one (num2);
                    if (greater_number == 0)
                    {  
                      quotient = packed_string_integer_copy_number (quotient, num1);
                      quotient = packed_string_integer_set_status_flag (quotient, NONE);
                      remainder = packed_string_integer_initialize_to_zero (remainder);
                    }
                    else
                    {
                      temp_num1 = packed_string_integer_copy_number (temp_num1, num1);
                      temp_num1 = packed_string_integer_set_sign (temp_num1, positive);
                      quotient_and_remainder_list = _packed_string_integer_divide_on_positive_integers_returning_quotient_and_remainder_high_performance (temp_num1, num2);
                      if (quotient_and_remainder_list != NULL)
                      {
                        if (quotient_and_remainder_list->element != NULL)
                        {
                          quotient_and_remainder_list->element = packed_string_integer_set_sign (quotient_and_remainder_list->element, negative);
                        }
                        if (quotient_and_remainder_list->next_element != NULL)
                        {
                          if (quotient_and_remainder_list->next_element->element != NULL)
                          {
                            quotient_and_remainder_list->next_element->element = packed_string_integer_set_sign (quotient_and_remainder_list->next_element->element, negative);
                          }
                        }
                      }
                    }
                  }
                  else
                  {
                    if (greater_number == -2)
                    {
                      quotient = packed_string_integer_initialize_to_undefined (quotient); 
                      quotient = packed_string_integer_set_status_flag (quotient, INTERNAL_ERROR);
                      remainder = packed_string_integer_initialize_to_undefined (remainder); 
                      remainder = packed_string_integer_set_status_flag (remainder, INTERNAL_ERROR);
                    }
                  }
                }
              }
            }
            else
            {
              quotient = packed_string_integer_initialize_to_undefined (quotient); 
              quotient = packed_string_integer_set_status_flag (quotient, INTERNAL_ERROR);
              remainder = packed_string_integer_initialize_to_undefined (remainder); 
              remainder = packed_string_integer_set_status_flag (remainder, INTERNAL_ERROR);
            }
          }
          else
          {
            if (num2->sign == negative)
            {
              if ((num1->left_of_decimal != NULL) && (num2->left_of_decimal != NULL))
              {
                greater_number = packed_string_integer_determine_absolute_value_larger_of_two_integers (num1, num2);
                if (greater_number == 0)
                {
                  quotient = packed_string_integer_set_value (quotient, "1");
                  quotient = packed_string_integer_set_status_flag (quotient, NONE);
                  remainder = packed_string_integer_initialize_to_zero (remainder);
                }
                else
                {
                  if (greater_number == -1)
                  {
                    quotient =  packed_string_integer_initialize_to_zero (quotient);
                    remainder = packed_string_integer_copy_number (remainder, num1);
                  }
                  else
                  {
                    if (greater_number == 1)
                    {
                      greater_number = packed_string_integer_determine_absolute_value_number_greater_than_one (num2);
                      if (greater_number == 0)
                      {  
                        quotient = packed_string_integer_copy_number (quotient, num1);
                        quotient = packed_string_integer_set_sign (quotient, positive);
                        quotient = packed_string_integer_set_status_flag (quotient, NONE);
                        remainder = packed_string_integer_initialize_to_zero (remainder);
                      }
                      else
                      {
                        temp_num1 = packed_string_integer_copy_number (temp_num1, num1);
                        temp_num1 = packed_string_integer_set_sign (temp_num1, positive);
                        temp_num2 = packed_string_integer_copy_number (temp_num2, num2);
                        temp_num2 = packed_string_integer_set_sign (temp_num2, positive);
                        quotient_and_remainder_list = _packed_string_integer_divide_on_positive_integers_returning_quotient_and_remainder_high_performance (temp_num1, temp_num2);
                        if (quotient_and_remainder_list != NULL)
                        {
                          if (quotient_and_remainder_list->next_element != NULL)
                          {
                            if (quotient_and_remainder_list->next_element->element != NULL)
                            {
                              quotient_and_remainder_list->next_element->element = packed_string_integer_set_sign (quotient_and_remainder_list->next_element->element, negative);
                            }
                          }
                        }
                      }
                    }
                    else
                    {
                      if (greater_number == -2)
                      {
                        quotient = packed_string_integer_initialize_to_undefined (quotient); 
                        quotient = packed_string_integer_set_status_flag (quotient, INTERNAL_ERROR);
                        remainder = packed_string_integer_initialize_to_undefined (remainder); 
                        remainder = packed_string_integer_set_status_flag (remainder, INTERNAL_ERROR);
                      }
                    }
                  }
                }
              }
              else
              {
                quotient = packed_string_integer_initialize_to_undefined (quotient); 
                quotient = packed_string_integer_set_status_flag (quotient, INTERNAL_ERROR);
                remainder = packed_string_integer_initialize_to_undefined (remainder); 
                remainder = packed_string_integer_set_status_flag (remainder, INTERNAL_ERROR);
              }
            }
            else
            {
              if (num2->sign == zero)
              {
                quotient = packed_string_integer_initialize_to_undefined (quotient); 
                quotient = packed_string_integer_set_status_flag (quotient, DIVIDE_BY_ZERO);
                remainder = packed_string_integer_initialize_to_undefined (remainder); 
                remainder = packed_string_integer_set_status_flag (remainder, DIVIDE_BY_ZERO);
              }
              else
              {
                if (num2->sign == undefined)
                {
                  quotient = packed_string_integer_initialize_to_undefined (quotient); 
                  quotient = packed_string_integer_set_status_flag (quotient, INTERNAL_ERROR);
                  remainder = packed_string_integer_initialize_to_undefined (remainder); 
                  remainder = packed_string_integer_set_status_flag (remainder, INTERNAL_ERROR);
                }
              }
            }
          }
        }
        else
        {
          if (num1->sign == undefined)
          {
            quotient = packed_string_integer_initialize_to_undefined (quotient); 
            quotient = packed_string_integer_set_status_flag (quotient, INTERNAL_ERROR);
            remainder = packed_string_integer_initialize_to_undefined (remainder); 
            remainder = packed_string_integer_set_status_flag (remainder, INTERNAL_ERROR);
          }
        }
      }       
    }
  }
  if (quotient_and_remainder_list != NULL)
  {
// ****************************************************************************************
// * Under normal circumstances one of the following cases applies:                       *
// *                                                                                      *
// * CASE 1: quotient and remainder are not NULL and quotient and_remainder_list is NULL. *
// * CASE 2: quotient and remainder are NULL and quotient_and_remainder_list is NOT NULL. *
// *                                                                                      *
// * The two cases above are meant to be mutually-exclusive. Thus, releasing memory below *
// * is an unusual situation to avoid a memory leak.                                      *
// ****************************************************************************************
    quotient  = packed_string_integer_release_memory (quotient);
    remainder = packed_string_integer_release_memory (remainder);
  }
  else
  {
    remainder_element = (psint_list_node *) malloc(sizeof(psint_list_node));
    if (remainder_element != NULL)
    {
      remainder_element->element = remainder;
      remainder_element->next_element = NULL;
      quotient_element = (psint_list_node *) malloc(sizeof(psint_list_node));
      if (quotient_element != NULL)
      {
        quotient_element->element = quotient;
        quotient_element->next_element = remainder_element;
        quotient_and_remainder_list = quotient_element;
      }
      else
      {
        free (remainder_element);
        remainder_element = NULL;
      }
    }
  }
  return quotient_and_remainder_list;
}




// ***********************************************************************************************************************************************
// * _packed_string_integer_divide_on_positive_integers                                                                                          *
// *                                                                                                                                             *
// * This is the internal subroutine that computes the actual division of packed string-based integer num1 and packed string-based integer num2. *
// * This function should not be called directly. Instead, it should be called through subroutine packed_string_integer_divide .                 *
// * NOTE: num1 and num2 must be positive integers before calling this internal subroutine.                                                      *
// ***********************************************************************************************************************************************
psint * _packed_string_integer_divide_on_positive_integers (psint *quotient_result, psint *num1, psint *num2)
{
  psint *numerator, *denominator, *temp_denominator, *quotient, *temp_quotient, *temp_numerator, *power_of_ten, *constant_1;
  long long int number_of_digits_in_numerator, number_of_digits_in_denominator, number_of_digits_difference;
  int done, greater_number;

  numerator        = NULL;
  denominator      = NULL;
  temp_numerator   = NULL;
  temp_denominator = NULL;
  temp_quotient    = NULL;
  quotient         = NULL;
  power_of_ten     = NULL;
  constant_1       = NULL;
  number_of_digits_in_numerator   = 0;
  number_of_digits_in_denominator = 0;
  if (quotient_result != NULL)
  {
    quotient_result = packed_string_integer_component_release_memory (quotient_result);
  }
  if ((num1 != NULL) && (num2 != NULL))
  {
    if ((num1->left_of_decimal != NULL) && (num2->left_of_decimal != NULL))
    {
      constant_1  = packed_string_integer_set_value (constant_1, "1");
      numerator   = packed_string_integer_copy_number (numerator, num1);
      denominator = packed_string_integer_copy_number (denominator, num2);
      quotient    = packed_string_integer_initialize_to_zero (quotient);
    }
  }
  if ((numerator != NULL) && (denominator != NULL) && (constant_1 != NULL))
  {
    number_of_digits_in_numerator   = count_num_digits_in_packed_string_integer (numerator);
    number_of_digits_in_denominator = count_num_digits_in_packed_string_integer (denominator);
    if (number_of_digits_in_numerator >= number_of_digits_in_denominator)
    {
      done = FALSE;
      number_of_digits_difference = number_of_digits_in_numerator - number_of_digits_in_denominator;
      greater_number = packed_string_integer_determine_absolute_value_larger_of_two_integers (numerator, denominator);
      if (greater_number == -1)
      {
        done = TRUE;
      }
      while ((number_of_digits_difference >= 0) && (!done))
      {
        power_of_ten = packed_string_integer_release_memory (power_of_ten);
        power_of_ten = packed_string_integer_shift_digits_left (constant_1, number_of_digits_difference); // product = temp_product * 10^i 
        temp_denominator = packed_string_integer_shift_digits_left (denominator, number_of_digits_difference); // product = temp_product * 10^i 
        temp_denominator = packed_string_integer_set_sign (temp_denominator, positive);
        greater_number = packed_string_integer_determine_absolute_value_larger_of_two_integers (numerator, temp_denominator);
        while (((greater_number == 1) || (greater_number == 0)) && (!done))
        {
          temp_quotient = packed_string_integer_add (temp_quotient, quotient, power_of_ten);
          quotient      = packed_string_integer_component_release_memory (quotient);
          quotient      = packed_string_integer_copy_number (quotient, temp_quotient);
          temp_quotient = packed_string_integer_release_memory (temp_quotient);
          temp_numerator = packed_string_integer_subtract (temp_numerator, numerator, temp_denominator);
          numerator      = packed_string_integer_release_memory (numerator);
          numerator      = packed_string_integer_copy_number (numerator, temp_numerator);
          temp_numerator = packed_string_integer_release_memory (temp_numerator);
          greater_number = packed_string_integer_determine_absolute_value_larger_of_two_integers (numerator, temp_denominator);
        }
        greater_number = packed_string_integer_determine_absolute_value_larger_of_two_integers (numerator, denominator);
        if (greater_number == -1)
        {
          done = TRUE;
        }
        number_of_digits_difference--;
      }
      quotient_result = packed_string_integer_copy_number (quotient_result, quotient);
    }
  }
  if (constant_1 != NULL)
  {
    constant_1 = packed_string_integer_release_memory (constant_1);
  }
  if (power_of_ten != NULL)
  {
    power_of_ten = packed_string_integer_release_memory (power_of_ten);
  }
  if (temp_numerator != NULL)
  {
    temp_numerator = packed_string_integer_release_memory (temp_numerator);
  }
  if (numerator != NULL)
  {
    numerator = packed_string_integer_release_memory (numerator);
  }
  if (temp_denominator != NULL)
  {
    temp_denominator = packed_string_integer_release_memory (temp_denominator);
  }
  if (denominator != NULL)
  {
    denominator = packed_string_integer_release_memory (denominator);
  }
  if (temp_quotient != NULL)
  {
    temp_quotient = packed_string_integer_release_memory (temp_quotient);
  }
  if (quotient != NULL)
  {
    quotient = packed_string_integer_release_memory (quotient);
  }
  return quotient_result;
}



// **************************************************************************************************
// * packed_string_integer_divide                                                                   *
// *                                                                                                *
// * Call this subroutine to divide two packed string-based integers together.                      *
// *                                                                                                *
// * Inputs: num1 (packed string-based integer) and num2 (packed string-based integer).             *
// * Output: A string-based integer representing the quotient of num1 and num2 (with no remainder). *
// **************************************************************************************************
psint * packed_string_integer_divide (psint *quotient, psint *num1, psint *num2)
{
  psint *temp_num1, *temp_num2;
  int greater_number;

  temp_num1  = NULL;
  temp_num2  = NULL;
// *************************************************************************
// * Release any previously used memory otherwise we'd have a memory leak. *
// *************************************************************************
  if (quotient != NULL)
  {
    quotient = packed_string_integer_component_release_memory (quotient);
  }
  if ((num1 != NULL) && (num2 != NULL))
  {
    if (num1->sign == zero)
    {
      if ((num2->sign == positive) || (num2->sign == negative))
      {
        quotient = packed_string_integer_initialize_to_zero (quotient);
      }
      else
      {
        if (num2->sign == zero)
        {
          quotient = packed_string_integer_initialize_to_undefined (quotient); 
          quotient = packed_string_integer_set_status_flag (quotient, DIVIDE_BY_ZERO);
        }
        else
        {
          if (num2->sign == undefined)
          {
            quotient = packed_string_integer_initialize_to_undefined (quotient); 
            quotient = packed_string_integer_set_status_flag (quotient, INTERNAL_ERROR);
          }
        }
      }
    }
    else
    {
      if (num1->sign == positive)
      {
        if (num2->sign == positive)
        {
          if ((num1->left_of_decimal != NULL) && (num2->left_of_decimal != NULL))
          {
            greater_number = packed_string_integer_determine_absolute_value_larger_of_two_integers (num1, num2);
            if (greater_number == 0)
            {
              quotient = packed_string_integer_set_value (quotient, "1");
              quotient = packed_string_integer_set_status_flag (quotient, NONE);
            }
            else
            {
              if (greater_number == -1)
              {
                quotient = packed_string_integer_initialize_to_zero (quotient);
              }
              else
              {
                if (greater_number == 1)
                {
                  greater_number = packed_string_integer_determine_absolute_value_number_greater_than_one (num2);
                  if (greater_number == 0)
                  {  
                    quotient = packed_string_integer_copy_number (quotient, num1);
                    quotient = packed_string_integer_set_status_flag (quotient, NONE);
                  }
                  else
                  {
                    quotient = _packed_string_integer_divide_on_positive_integers (quotient, num1, num2);
                  }
                }
                else
                {
                  if (greater_number == -2)
                  {
                    quotient = packed_string_integer_initialize_to_undefined (quotient); 
                    quotient = packed_string_integer_set_status_flag (quotient, INTERNAL_ERROR);
                  }
                }
              }
            }
          }
          else
          {
            quotient = packed_string_integer_initialize_to_undefined (quotient); 
            quotient = packed_string_integer_set_status_flag (quotient, INTERNAL_ERROR);
          }
        }
        else
        {
          if (num2->sign == negative)
          {
            if ((num1->left_of_decimal != NULL) && (num2->left_of_decimal != NULL))
            {
              greater_number = packed_string_integer_determine_absolute_value_larger_of_two_integers (num1, num2);
              if (greater_number == 0)
              {
                quotient = packed_string_integer_set_value (quotient, "1");
                quotient = packed_string_integer_set_sign (quotient, negative);
                quotient = packed_string_integer_set_status_flag (quotient, NONE);
              }
              else
              {
                if (greater_number == -1)
                {
                  quotient = packed_string_integer_initialize_to_zero (quotient);
                }
                else
                {
                  if (greater_number == 1)
                  {
                    greater_number = packed_string_integer_determine_absolute_value_number_greater_than_one (num2);
                    if (greater_number == 0)
                    {  
                      quotient = packed_string_integer_copy_number (quotient, num1);
                      quotient = packed_string_integer_set_status_flag (quotient, NONE);
                    }
                    else
                    {
                      temp_num2 = packed_string_integer_copy_number (temp_num2, num2);
                      temp_num2 = packed_string_integer_set_sign (temp_num2, positive);
                      quotient  = _packed_string_integer_divide_on_positive_integers (quotient, num1, temp_num2);
                      quotient  = packed_string_integer_set_sign (quotient, negative);
                      quotient = packed_string_integer_set_status_flag (quotient, NONE);
                    }
                  }
                  else
                  {
                    if (greater_number == -2)
                    {
                      quotient = packed_string_integer_initialize_to_undefined (quotient); 
                      quotient = packed_string_integer_set_status_flag (quotient, INTERNAL_ERROR);
                    }
                  }
                }
              }
            }
          }
          else
          {
            if (num2->sign == zero)
            {
              quotient = packed_string_integer_initialize_to_undefined (quotient); 
              quotient = packed_string_integer_set_status_flag (quotient, DIVIDE_BY_ZERO);
            }
            else
            {
              if (num2->sign == undefined)
              {
                quotient = packed_string_integer_initialize_to_undefined (quotient); 
                quotient = packed_string_integer_set_status_flag (quotient, INTERNAL_ERROR);
              }
            }
          }
        }
      }
      else
      {
        if (num1->sign == negative)
        {
          if (num2->sign == positive)
          {
            if ((num1->left_of_decimal != NULL) && (num2->left_of_decimal != NULL))
            {
              greater_number = packed_string_integer_determine_absolute_value_larger_of_two_integers (num1, num2);
              if (greater_number == 0)
              {
                quotient = packed_string_integer_set_value (quotient, "-1");
                quotient = packed_string_integer_set_status_flag (quotient, NONE);
              }
              else
              {
                if (greater_number == -1)
                {
                  quotient = packed_string_integer_initialize_to_zero (quotient);
                }
                else
                {
                  if (greater_number == 1)
                  {
                    greater_number = packed_string_integer_determine_absolute_value_number_greater_than_one (num2);
                    if (greater_number == 0)
                    {  
                      quotient = packed_string_integer_copy_number (quotient, num1);
                      quotient = packed_string_integer_set_status_flag (quotient, NONE);
                    }
                    else
                    {
                      temp_num1 = packed_string_integer_copy_number (temp_num1, num1);
                      temp_num1 = packed_string_integer_set_sign (temp_num1, positive);
                      quotient = _packed_string_integer_divide_on_positive_integers (quotient, temp_num1, num2);
                      quotient = packed_string_integer_set_sign (quotient, negative);
                      quotient = packed_string_integer_set_status_flag (quotient, NONE);
                    }
                  }
                  else
                  {
                    if (greater_number == -2)
                    {
                      quotient = packed_string_integer_initialize_to_undefined (quotient); 
                      quotient = packed_string_integer_set_status_flag (quotient, INTERNAL_ERROR);
                    }
                  }
                }
              }
            }
            else
            {
              quotient = packed_string_integer_initialize_to_undefined (quotient); 
              quotient = packed_string_integer_set_status_flag (quotient, INTERNAL_ERROR);
            }
          }
          else
          {
            if (num2->sign == negative)
            {
              if ((num1->left_of_decimal != NULL) && (num2->left_of_decimal != NULL))
              {
                greater_number = packed_string_integer_determine_absolute_value_larger_of_two_integers (num1, num2);
                if (greater_number == 0)
                {
                  quotient = packed_string_integer_set_value (quotient, "1");
                  quotient = packed_string_integer_set_status_flag (quotient, NONE);
                }
                else
                {
                  if (greater_number == -1)
                  {
                    quotient =  packed_string_integer_initialize_to_zero (quotient);
                  }
                  else
                  {
                    if (greater_number == 1)
                    {
                      greater_number = packed_string_integer_determine_absolute_value_number_greater_than_one (num2);
                      if (greater_number == 0)
                      {  
                        quotient = packed_string_integer_copy_number (quotient, num1);
                        quotient = packed_string_integer_set_sign (quotient, positive);
                        quotient = packed_string_integer_set_status_flag (quotient, NONE);
                      }
                      else
                      {
                        temp_num1 = packed_string_integer_copy_number (temp_num1, num1);
                        temp_num1 = packed_string_integer_set_sign (temp_num1, positive);
                        temp_num2 = packed_string_integer_copy_number (temp_num2, num2);
                        temp_num2 = packed_string_integer_set_sign (temp_num2, positive);
                        quotient = _packed_string_integer_divide_on_positive_integers (quotient, temp_num1, temp_num2);
                      }
                    }
                    else
                    {
                      if (greater_number == -2)
                      {
                        quotient = packed_string_integer_initialize_to_undefined (quotient); 
                        quotient = packed_string_integer_set_status_flag (quotient, INTERNAL_ERROR);
                      }
                    }
                  }
                }
              }
              else
              {
                quotient = packed_string_integer_initialize_to_undefined (quotient); 
                quotient = packed_string_integer_set_status_flag (quotient, INTERNAL_ERROR);
              }
            }
            else
            {
              if (num2->sign == zero)
              {
                quotient = packed_string_integer_initialize_to_undefined (quotient); 
                quotient = packed_string_integer_set_status_flag (quotient, DIVIDE_BY_ZERO);
              }
              else
              {
                if (num2->sign == undefined)
                {
                  quotient = packed_string_integer_initialize_to_undefined (quotient); 
                  quotient = packed_string_integer_set_status_flag (quotient, INTERNAL_ERROR);
                }
              }
            }
          }
        }
        else
        {
          if (num1->sign == undefined)
          {
            quotient = packed_string_integer_initialize_to_undefined (quotient); 
            quotient = packed_string_integer_set_status_flag (quotient, INTERNAL_ERROR);
          }
        }
      }       
    }
  }
  return quotient;
}  





// *******************************************************************************************************************************************
// * _packed_string_integer_modulo_on_positive_integers                                                                                      *
// *                                                                                                                                         *
// * This is the internal subroutine that computes the remainder from an integer divison of two packed string-based integers, num1 and num2. *
// *                                                                                                                                         *
// * This function should not be called directly. Instead, it should be called through subroutine packed_string_integer_multiply.            *
// * NOTE: num1 and num2 must be converted to positive integers for this function to perform correctly.                                      *
// *******************************************************************************************************************************************
psint * _packed_string_integer_modulo_on_positive_integers (psint *remainder, psint *num1, psint *num2)
{
  psint *numerator, *denominator, *temp_denominator, *temp_numerator, *power_of_ten, *constant_1;
  long long int number_of_digits_in_numerator, number_of_digits_in_denominator, number_of_digits_difference;
  int done, greater_number;

  numerator        = NULL;
  denominator      = NULL;
  temp_numerator   = NULL;
  temp_denominator = NULL;
  power_of_ten     = NULL;
  constant_1       = NULL;
  number_of_digits_in_numerator   = 0;
  number_of_digits_in_denominator = 0;
  if (remainder != NULL)
  {
    remainder = packed_string_integer_component_release_memory (remainder);
  }
  if ((num1 != NULL) && (num2 != NULL))
  {
    if ((num1->left_of_decimal != NULL) && (num2->left_of_decimal != NULL))
    {
      constant_1  = packed_string_integer_set_value (constant_1, "1");
      numerator   = packed_string_integer_copy_number (numerator, num1);
      denominator = packed_string_integer_copy_number (denominator, num2);
    }
  }
  if ((numerator != NULL) && (denominator != NULL) && (constant_1 != NULL))
  {
    number_of_digits_in_numerator   = count_num_digits_in_packed_string_integer (numerator);
    number_of_digits_in_denominator = count_num_digits_in_packed_string_integer (denominator);
    if (number_of_digits_in_numerator >= number_of_digits_in_denominator)
    {
      done = FALSE;
      number_of_digits_difference = number_of_digits_in_numerator - number_of_digits_in_denominator;
      greater_number = packed_string_integer_determine_absolute_value_larger_of_two_integers (numerator, denominator);
      if (greater_number == -1)
      {
        done = TRUE;
      }
      while ((number_of_digits_difference >= 0) && (!done))
      {
        power_of_ten = packed_string_integer_component_release_memory (power_of_ten);
        power_of_ten = packed_string_integer_shift_digits_left (constant_1, number_of_digits_difference); // product = temp_product * 10^i 
        temp_denominator = packed_string_integer_shift_digits_left (denominator, number_of_digits_difference); // product = temp_product * 10^i 
        temp_denominator = packed_string_integer_set_sign (temp_denominator, positive);
        greater_number = packed_string_integer_determine_absolute_value_larger_of_two_integers (numerator, temp_denominator);
        while (((greater_number == 1) || (greater_number == 0)) && (!done))
        {
          temp_numerator = packed_string_integer_subtract (temp_numerator, numerator, temp_denominator);
          numerator      = packed_string_integer_component_release_memory (numerator);
          numerator      = packed_string_integer_copy_number (numerator, temp_numerator);
          temp_numerator = packed_string_integer_release_memory (temp_numerator);
          greater_number = packed_string_integer_determine_absolute_value_larger_of_two_integers (numerator, temp_denominator);
        }
        greater_number = packed_string_integer_determine_absolute_value_larger_of_two_integers (numerator, denominator);
        if (greater_number == -1)
        {
          done = TRUE;
        }
        number_of_digits_difference--;
      }
      remainder = packed_string_integer_copy_number (remainder, numerator);
    }
    else
    {
      remainder = packed_string_integer_copy_number (remainder, numerator);
    }
  }
  if (constant_1 != NULL)
  {
    constant_1 = packed_string_integer_release_memory (constant_1);
  }
  if (power_of_ten != NULL)
  {
    power_of_ten = packed_string_integer_release_memory (power_of_ten);
  }
  if (temp_numerator != NULL)
  {
    temp_numerator = packed_string_integer_release_memory (temp_numerator);
  }
  if (temp_denominator != NULL)
  {
    temp_denominator = packed_string_integer_release_memory (temp_denominator);
  }
  if (numerator != NULL)
  {
    numerator = packed_string_integer_release_memory (numerator);
  }
  if (denominator != NULL)
  {
    denominator = packed_string_integer_release_memory (denominator);
  }
  return remainder;
}




// *********************************************************************************************************
// * packed_string_integer_modulo                                                                          *
// *                                                                                                       *
// * Call this subroutine to return the remainder when dividing two packed string-based integers together. *
// *                                                                                                       *
// * Inputs: num1 (packed string-based integer) and num2 (packed string-based integer).                    *
// * Output: A packed string-based integer representing the remainder of num1 divided by num2.             *
// *********************************************************************************************************
psint * packed_string_integer_modulo (psint *remainder, psint *num1, psint *num2)
{
  psint *temp_num1, *temp_num2;
  int greater_number;

  temp_num1  = NULL;
  temp_num2  = NULL;
// *************************************************************************
// * Release any previously used memory otherwise we'd have a memory leak. *
// *************************************************************************
  if (remainder != NULL)
  {
    remainder = packed_string_integer_component_release_memory (remainder);
  }
  if ((num1 != NULL) && (num2 != NULL))
  {
    if (num1->sign == zero)
    {
      if ((num2->sign == positive) || (num2->sign == negative))
      {
        remainder = packed_string_integer_initialize_to_zero (remainder);
      }
      else
      {
        if (num2->sign == zero)
        {
          remainder = packed_string_integer_initialize_to_undefined (remainder); 
          remainder = packed_string_integer_set_status_flag (remainder, DIVIDE_BY_ZERO);
        }
        else
        {
          if (num2->sign == undefined)
          {
            remainder = packed_string_integer_initialize_to_undefined (remainder); 
            remainder = packed_string_integer_set_status_flag (remainder, INTERNAL_ERROR);
          }
        }
      }
    }
    else
    {
      if (num1->sign == positive)
      {
        if (num2->sign == positive)
        {
          if ((num1->left_of_decimal != NULL) && (num2->left_of_decimal != NULL))
          {
            greater_number = packed_string_integer_determine_absolute_value_larger_of_two_integers (num1, num2);
            if (greater_number == 0)
            {
              remainder = packed_string_integer_initialize_to_zero (remainder);
            }
            else
            {
              if (greater_number == -1)
              {
                remainder = packed_string_integer_copy_number (remainder, num1);
              }
              else
              {
                if (greater_number == 1)
                {
                  greater_number = packed_string_integer_determine_absolute_value_number_greater_than_one (num2);
                  if (greater_number == 0)
                  {  
                    remainder = packed_string_integer_initialize_to_zero (remainder);
                  }
                  else
                  {
                    remainder = _packed_string_integer_modulo_on_positive_integers (remainder, num1, num2);
                  }
                }
                else
                {
                  if (greater_number == -2)
                  {
                    remainder = packed_string_integer_initialize_to_undefined (remainder); 
                    remainder = packed_string_integer_set_status_flag (remainder, INTERNAL_ERROR);
                  }
                }
              }
            }
          }
          else
          {
            remainder = packed_string_integer_initialize_to_undefined (remainder); 
            remainder = packed_string_integer_set_status_flag (remainder, INTERNAL_ERROR);
          }
        }
        else
        {
          if (num2->sign == negative)
          {
            temp_num2 = packed_string_integer_copy_number (temp_num2, num2);
            temp_num2 = packed_string_integer_set_sign (temp_num2, positive);
            remainder = _packed_string_integer_modulo_on_positive_integers (remainder, num1, temp_num2);
          }
          else
          {
            if (num2->sign == zero)
            {
              remainder = packed_string_integer_initialize_to_undefined (remainder); 
              remainder = packed_string_integer_set_status_flag (remainder, DIVIDE_BY_ZERO);
            }
            else
            {
              if (num2->sign == undefined)
              {
                remainder = packed_string_integer_initialize_to_undefined (remainder); 
                remainder = packed_string_integer_set_status_flag (remainder, INTERNAL_ERROR);
              }
            }
          }
        }
      }
      else
      {
        if (num1->sign == negative)
        {
          if (num2->sign == positive)
          {
            if ((num1->left_of_decimal != NULL) && (num2->left_of_decimal != NULL))
            {
              greater_number = packed_string_integer_determine_absolute_value_larger_of_two_integers (num1, num2);
              if (greater_number == 0)
              {
                remainder = packed_string_integer_initialize_to_zero (remainder);
              }
              else
              {
                if (greater_number == -1)
                {
                  remainder = packed_string_integer_copy_number (remainder, num1);
                }
                else
                {
                  if (greater_number == 1)
                  {
                    greater_number = packed_string_integer_determine_absolute_value_number_greater_than_one (num2);
                    if (greater_number == 0)
                    {  
                      remainder = packed_string_integer_initialize_to_zero (remainder);
                    }
                    else
                    {
                      temp_num1 = packed_string_integer_copy_number (temp_num1, num1);
                      temp_num1 = packed_string_integer_set_sign (temp_num1, positive);
                      remainder = _packed_string_integer_modulo_on_positive_integers (remainder, temp_num1, num2);
                    }
                  }
                  else
                  {
                    if (greater_number == -2)
                    {
                      remainder = packed_string_integer_initialize_to_undefined (remainder); 
                      remainder = packed_string_integer_set_status_flag (remainder, INTERNAL_ERROR);
                    }
                  }
                }
              }
            }
            else
            {
              remainder = packed_string_integer_initialize_to_undefined (remainder); 
              remainder = packed_string_integer_set_status_flag (remainder, INTERNAL_ERROR);
            }
          }
          else
          {
            if (num2->sign == negative)
            {
              if ((num1->left_of_decimal != NULL) && (num2->left_of_decimal != NULL))
              {
                greater_number = packed_string_integer_determine_absolute_value_larger_of_two_integers (num1, num2);
                if (greater_number == 0)
                {
                  remainder = packed_string_integer_initialize_to_zero (remainder);
                }
                else
                {
                  if (greater_number == -1)
                  {
                    remainder = packed_string_integer_copy_number (remainder, num1);
                  }
                  else
                  {
                    if (greater_number == 1)
                    {
                      greater_number = packed_string_integer_determine_absolute_value_number_greater_than_one (num2);
                      if (greater_number == 0)
                      {  
                        remainder = packed_string_integer_initialize_to_zero (remainder);
                      }
                      else
                      {
                        temp_num1 = packed_string_integer_copy_number (temp_num1, num1);
                        temp_num1 = packed_string_integer_set_sign (temp_num1, positive);
                        temp_num2 = packed_string_integer_copy_number (temp_num2, num2);
                        temp_num2 = packed_string_integer_set_sign (temp_num2, positive);
                        remainder = _packed_string_integer_modulo_on_positive_integers (remainder, temp_num1, temp_num2);
                      }
                    }
                    else
                    {
                      if (greater_number == -2)
                      {
                        remainder = packed_string_integer_initialize_to_undefined (remainder); 
                        remainder = packed_string_integer_set_status_flag (remainder, INTERNAL_ERROR);
                      }
                    }
                  }
                }
              }
              else
              {
                remainder = packed_string_integer_initialize_to_undefined (remainder); 
                remainder = packed_string_integer_set_status_flag (remainder, INTERNAL_ERROR);
              }
            }
            else
            {
              if (num2->sign == zero)
              {
                remainder = packed_string_integer_initialize_to_undefined (remainder); 
                remainder = packed_string_integer_set_status_flag (remainder, DIVIDE_BY_ZERO);
              }
              else
              {
                if (num2->sign == undefined)
                {
                  remainder = packed_string_integer_initialize_to_undefined (remainder); 
                  remainder = packed_string_integer_set_status_flag (remainder, INTERNAL_ERROR);
                }
              }
            }
          }
        }
        else
        {
          if (num1->sign == undefined)
          {
            remainder = packed_string_integer_initialize_to_undefined (remainder); 
            remainder = packed_string_integer_set_status_flag (remainder, INTERNAL_ERROR);
          }
        }
      }       
    }
  }
  if (temp_num1 != NULL)
  {
    temp_num1 = packed_string_integer_release_memory (temp_num1);
  }
  if (temp_num2 != NULL)
  {
    temp_num2 = packed_string_integer_release_memory (temp_num2);
  }
  return remainder;
}




// *************************************************************************
// * packed_string_integer_display                                         *
// *                                                                       *
// * This subroutine displays a packed string-based integer to the screen. *
// *************************************************************************
void packed_string_integer_display (psint *number, int display_unary_plus)
{
  psnc *temp;
  unsigned char tempbyte, nibble_high, nibble_low, packed_byte;
  int i, state;

  temp = NULL;
  if (number != NULL)
  {
    switch (number->sign)
    {
      case negative:
        putchar ('-');
      break;
      case zero:
        putchar ('0');
      break;
      case positive:
        if (display_unary_plus)
        {
          putchar ('+');
        }
      break;
      case undefined:
        printf ("undefined");
      break;
      default:
      break;
    }
    if (number->left_of_decimal != NULL)
    {
      if ((number->sign == positive) || (number->sign == negative))
      {
        state = 0;
        temp = number->left_of_decimal->last_number_block;
        while (temp != NULL)
        {
          i = temp->highest_digit_position;
          //printf ("highest_digit_position: %d\n", i);
          if ((i >= 0) && (i < MAX_PACKED_NUMBER_BLOCK_SIZE))
          {
            while (i >= 0)
            {
              //printf ("state = %d, i = %d\n", state, i);
              //fflush (stdout);
              packed_byte = temp->packed_number_block[i];
              nibble_low  = packed_byte & 0x0f;
              nibble_high = (packed_byte & 0xf0) >> 4;
              //printf ("\nbyte = %02x, nibble_high = %x, nibble_low = %x\n", packed_byte, nibble_high, nibble_low);
              switch (state)
              {
                case 0:
                  if ((nibble_high >= 1) && (nibble_high <= 9))
                  {
                    tempbyte = nibble_high + '0';
                    putchar (tempbyte);
                    if ((nibble_low >= 0) && (nibble_low <= 9))
                    {
                      tempbyte = nibble_low + '0';
                      putchar (tempbyte);
                    }
                    state = 10;
                  }
                  else
                  {
                    if (nibble_high == 0)
                    {
                      if ((nibble_low >= 1) && (nibble_low <= 9))
                      {
                        tempbyte = nibble_low + '0';
                        putchar (tempbyte);
                        state = 10;
                      }
                      else
                      {
                        if (i == 0)
                        {
                          if (temp == number->left_of_decimal)
                          {
                            tempbyte = '0';
                            putchar (tempbyte);
                          }
                        }
                      }
                    }
                  }
                break;
                case 10:
                  if ((nibble_high >= 0) && (nibble_high <= 9))
                  {
                    tempbyte = nibble_high + '0';
                    putchar (tempbyte);
                  }
                  if ((nibble_low >= 0) && (nibble_low <= 9))
                  {
                    tempbyte = nibble_low + '0';
                    putchar (tempbyte);
                  } 
                break;
                default:
                break;
              }
              i--;
            }
          }
          temp = temp->previous_number_block;
        } 
      } 
    }
  }
  else
  {
    printf ("UNDEFINED");
  }
}  




// *******************************************************************************************
// * packed_string_integer_determine_absolute_value_number_greater_than_one                  *
// *                                                                                         *
// * This subroutine determines if a string-based integer is greater than or equal to one.   *
// *                                                                                         *
// * If absolute value of number is greater than one: return +1                              *
// * If absolute value of number is equal to one:     return 0                               *
// * If absolute value of number is less than one:    return -1                              *
// *                                                                                         *
// * Note: a -2 indicates an error occurred and the larger number was not determined.        *
// *******************************************************************************************
int packed_string_integer_determine_absolute_value_number_greater_than_one (psint *number)
{
  psnc *temp_number_integer_component;
  int larger_number_result, first_number_block;
  unsigned char number_packed_byte, number_nibble_low, number_nibble_high;
  long long int i;

  temp_number_integer_component = NULL;
  larger_number_result = -2;
  first_number_block = TRUE;
  if (number != NULL)
  {
    if (number->left_of_decimal != NULL)
    {
      if ((number->sign == positive) || (number->sign == negative))
      {
        number_packed_byte = number->left_of_decimal->packed_number_block[0];
        number_nibble_low  = number_packed_byte & 0x0f;
        number_nibble_high = (number_packed_byte & 0xf0) >> 4;
        if (number_nibble_low >= 2)
        {
          larger_number_result = 1;
        }
        else
        {
          if ((number_nibble_low == 0) || (number_nibble_low == 1)) 
          {
            if (number_nibble_high > 0)
            {
              larger_number_result = 1;
            }
          }
        }
        temp_number_integer_component = number->left_of_decimal;
        while ((temp_number_integer_component != NULL) && (larger_number_result == -2))
        {
          if (first_number_block)
          {
            i = 1; // we've already looked at the 0th digit for the first number block. Skip it.
          }
          else
          {
            i = 0;
          }
          while ((i < MAX_PACKED_NUMBER_BLOCK_SIZE) && (larger_number_result == -2))
          {
            number_packed_byte = temp_number_integer_component->packed_number_block[i];
            number_nibble_low  = number_packed_byte & 0x0f;
            number_nibble_high = (number_packed_byte & 0xf0) >> 4;
            if (number_nibble_low >= 1)
            {
              larger_number_result = 1;
            }
            else
            {
              if (number_nibble_high >= 1)
              {
                larger_number_result = 1;
              }
            }
            i++;
          }
          first_number_block = FALSE;
          temp_number_integer_component = temp_number_integer_component->next_number_block;
        }
        if (temp_number_integer_component == NULL)
        {
          if (larger_number_result == -2)
          {
            larger_number_result = 0;
          }
        }
      }
    } 
    if (number->sign == zero)
    {
      larger_number_result = -1;
    }
  }
  return larger_number_result;
}




// ****************************************************************************************************
// * packed_string_integer_determine_absolute_value_larger_of_two_integers                            *
// *                                                                                                  *
// * This subroutine determines which of two input packed string-based integers is the larger number. *
// *                                                                                                  *
// * If absolute value of num1 is greater than absolute value of num2: return +1                      *
// * If absolute value of num1 is equal to absolute value of num2:     return 0                       *
// * If absolute value of num1 is less than absolute value of num2:    return -1                      *
// *                                                                                                  *
// * Note: a -2 indicates an error occurred and the larger number was not determined.                 *
// ****************************************************************************************************
int packed_string_integer_determine_absolute_value_larger_of_two_integers (psint *num1, psint *num2)
{
  psnc *tempA_num1, *tempA_num2, *tempB_num1, *tempB_num2;
  int i, larger_number_result, num1_and_num2_are_identical, found_digit_greater_than_zero;
  unsigned char num1_packed_byte, num2_packed_byte, num1_nibble_low, num2_nibble_low, num1_nibble_high, num2_nibble_high;
  char difference;

  tempA_num1 = NULL;
  tempA_num2 = NULL;
  tempB_num1 = NULL;
  tempB_num2 = NULL;
  larger_number_result          = -2;
  num1_and_num2_are_identical   = FALSE;
  found_digit_greater_than_zero = FALSE;
  if ((num1 != NULL) && (num2 != NULL))
  {
    if ((num1->left_of_decimal != NULL) && (num2->left_of_decimal != NULL))
    {
      if (((num1->sign == positive) || (num1->sign == negative)) && ((num2->sign == positive) || (num2->sign == negative)))
      {
        tempA_num1 = num1->left_of_decimal;
        tempA_num2 = num2->left_of_decimal;
        while ((tempA_num1->next_number_block != NULL) && (tempA_num2->next_number_block != NULL))
        {
          tempA_num1 = tempA_num1->next_number_block;
          tempA_num2 = tempA_num2->next_number_block;
        } 
        if ((tempA_num1->next_number_block == NULL) && (tempA_num2->next_number_block == NULL))
        {
// *******************************************************************************
// * num1 and num2 have the same number of digit datablocks.                     *
// *                                                                             *
// *                                                                             *
// * Begin at highest digit on num1 and num2 and work backwards to lowest digit. *
// *******************************************************************************
          difference = 0;
          while ((tempA_num1 != NULL) && (tempA_num2 != NULL) && (difference == 0))
          {
            i = MAX_PACKED_NUMBER_BLOCK_SIZE - 1;
            while ((i >= 0) && (difference == 0))
            {
              num1_packed_byte = tempA_num1->packed_number_block[i];
              num2_packed_byte = tempA_num2->packed_number_block[i];
              num1_nibble_low  = num1_packed_byte & 0x0f;
              num2_nibble_low  = num2_packed_byte & 0x0f;
              num1_nibble_high = (num1_packed_byte & 0xf0) >> 4;
              num2_nibble_high = (num2_packed_byte & 0xf0) >> 4;
              difference = num1_nibble_high - num2_nibble_high;
              if (difference == 0)
              {
                difference = num1_nibble_low - num2_nibble_low;
              }
              if (difference > 0)
              {
                larger_number_result = 1; // num1 is greater than num2
              }
              else
              {
                if (difference < 0)
                {
                  larger_number_result = -1; // num1 is less than num2
                }
              }
              if (difference == 0)
              {
                i--;
              }
            }
            if (difference == 0)
            {
              tempA_num1 = tempA_num1->previous_number_block;
              tempA_num2 = tempA_num2->previous_number_block;
            }
          }
          if (difference == 0)
          {
            num1_and_num2_are_identical = TRUE;
          }
        }
        else
        {
          if (tempA_num1->next_number_block != NULL)  // num1 has more digit datablocks than num2.
          {
// *********************************************************************************
// * Verify that at least one digit in num1's highest datablock is greater than 0. *
// *********************************************************************************
            tempB_num1 = num1->left_of_decimal->last_number_block;
            while ((tempB_num1 != tempA_num1) && (tempB_num1 != NULL) && (!found_digit_greater_than_zero))
            {
              i = MAX_PACKED_NUMBER_BLOCK_SIZE - 1;
              while ((i >= 0) && (!found_digit_greater_than_zero))
              {
// ***********************************************************************************************************
// * We do not need to unpack the packed_byte into a high and low nibble (to extract two BCD digits). Why?   *
// * Simply because if the packed_byte is greater than zero, we know for a fact that either the high nibble, *
// * low nibble, or both nibbles contains a non-zero digit. That alone means num1 is PHYSICALLY GREATER than *
// * num2.                                                                                                   *
// ***********************************************************************************************************
                num1_packed_byte = tempB_num1->packed_number_block[i];
                if (num1_packed_byte > 0)
                {
                  found_digit_greater_than_zero = TRUE;
                  larger_number_result = 1; // num1 is greater than num2
                }
                i--;
              }
              if (!found_digit_greater_than_zero)
              {
                tempB_num1 = tempB_num1->previous_number_block;
              }
            }
            if (!found_digit_greater_than_zero)
            {
              difference = 0;
              while ((tempA_num1 != NULL) && (tempA_num2 != NULL) && (difference == 0))
              {
                i = MAX_PACKED_NUMBER_BLOCK_SIZE - 1;
                while ((i >= 0) && (difference == 0))
                {
                  // unpack packed_bytes from num1 and num2. Then compare num1_high_nibble with num2_high_nibble and num1_low_nibble with num2_low_nibble.
                  num1_packed_byte = tempA_num1->packed_number_block[i];
                  num2_packed_byte = tempA_num2->packed_number_block[i];
                  num1_nibble_low  = num1_packed_byte & 0x0f;
                  num2_nibble_low  = num2_packed_byte & 0x0f;
                  num1_nibble_high = (num1_packed_byte & 0xf0) >> 4;
                  num2_nibble_high = (num2_packed_byte & 0xf0) >> 4;
                  difference = num1_nibble_high - num2_nibble_high;
                  if (difference == 0)
                  {
                    difference = num1_nibble_low - num2_nibble_low;
                  }
                  if (difference > 0)
                  {
                    larger_number_result = 1; // num1 is greater than num2
                  }
                  else
                  {
                    if (difference < 0)
                    {
                      larger_number_result = -1; // num1 is less than num2
                    }
                  }
                  if (difference == 0)
                  {
                    i--;
                  }
                }
                if (difference == 0)
                {
                  tempA_num1 = tempA_num1->previous_number_block;
                  tempA_num2 = tempA_num2->previous_number_block;
                }
              }
              if (difference == 0)
              {
                num1_and_num2_are_identical = TRUE;
              }
            }
          }
          else
          {
            if (tempA_num2->next_number_block != NULL)
            {
// *********************************************
// * num2 has more digit datablocks than num1. *
// *********************************************
    
// *********************************************************************************
// * Verify that at least one digit in num2's highest datablock is greater than 0. *
// *********************************************************************************
              tempB_num2 = num2->left_of_decimal->last_number_block;
              while ((tempB_num2 != tempA_num2) && (tempB_num2 != NULL) && (!found_digit_greater_than_zero))
              {
                i = MAX_PACKED_NUMBER_BLOCK_SIZE - 1;
                while ((i >= 0) && (!found_digit_greater_than_zero))
                {
// ***********************************************************************************************************
// * We do not need to unpack the packed_byte into a high and low nibble (to extract two BCD digits). Why?   *
// * Simply because if the packed_byte is greater than zero, we know for a fact that either the high nibble, *
// * low nibble, or both nibbles contains a non-zero digit. That alone means num1 is PHYSICALLY GREATER than *
// * num2.                                                                                                   *
// ***********************************************************************************************************
                  num2_packed_byte = tempB_num2->packed_number_block[i];
                  if (num2_packed_byte > 0)
                  {
                    found_digit_greater_than_zero = TRUE;
                    larger_number_result = -1; // num1 is less than num2
                  }
                  if (!found_digit_greater_than_zero)
                  {
                    i--;
                  }
                }
                if (!found_digit_greater_than_zero)
                {
                  tempB_num2 = tempB_num2->previous_number_block;
                }
              }
              if (!found_digit_greater_than_zero)
              {
                difference = 0;
                while ((tempA_num1 != NULL) && (tempA_num2 != NULL) && (difference == 0))
                {
                  i = MAX_PACKED_NUMBER_BLOCK_SIZE - 1;
                  while ((i >= 0) && (difference == 0))
                  {
                    // unpack packed_bytes from num1 and num2. Then compare num1_high_nibble with num2_high_nibble and num1_low_nibble with num2_low_nibble.
                    num1_packed_byte = tempA_num1->packed_number_block[i];
                    num2_packed_byte = tempA_num2->packed_number_block[i];
                    num1_nibble_low  = num1_packed_byte & 0x0f;
                    num2_nibble_low  = num2_packed_byte & 0x0f;
                    num1_nibble_high = (num1_packed_byte & 0xf0) >> 4;
                    num2_nibble_high = (num2_packed_byte & 0xf0) >> 4;
                    difference = num1_nibble_high - num2_nibble_high;
                    if (difference == 0)
                    {
                      difference = num1_nibble_low - num2_nibble_low;
                    }
                    if (difference > 0)
                    {
                      larger_number_result = 1; // num1 is greater than num2
                    }
                    else
                    {
                      if (difference < 0)
                      {
                        larger_number_result = -1; // num1 is less than num2
                      }
                    }
                    if (difference == 0)
                    {
                      i--;
                    }
                  }
                  if (difference == 0)
                  {
                    tempA_num1 = tempA_num1->previous_number_block;
                    tempA_num2 = tempA_num2->previous_number_block;
                  }
                }
                if (difference == 0)
                {
                  num1_and_num2_are_identical = TRUE;
                }
              }
            }
          }
        }
        if (num1_and_num2_are_identical)
        {
          larger_number_result = 0;
        }
      } 
      else
      {
        larger_number_result = -2;
      }
    }
    else
    {
      if (num1->sign == zero)
      {
        if (num2->sign == zero)
        {
          larger_number_result = 0;
        }
        else
        {
          if ((num2->sign == positive) || (num2->sign == negative))
          {
            larger_number_result = -1; // Reminder: This function evaluates the absolute values of num1 and num2 to determine which is larger.
          }
          else
          {
            larger_number_result = -2;
          }
        }
      }
      else
      {
        if ((num1->sign == positive) || (num1->sign == negative))
        {
          if (num2->sign == zero)
          {
            larger_number_result = 1; // Reminder: This function evaluates the absolute values of num1 and num2 to determine which is larger.
          }
        }
        else
        {
          larger_number_result = -2;
        }
      }
    }
  }
  return larger_number_result;
}





// ******************************************************************************************************************
// * packed_string_integer_greater_than                                                                             *
// *                                                                                                                *
// * This library determiness if packed string-based integer num1 is greater than packed string-based integer num2. *
// *                                                                                                                *
// * If num1 >  num2 return 1 (TRUE)                                                                                *
// * If num1 <= num2 return 0 (FALSE)                                                                               *
// *                                                                                                                *
// * If an error occurs, 0 (FALSE) is returned.                                                                     *
// ******************************************************************************************************************
unsigned char packed_string_integer_greater_than (psint *num1, psint *num2)
{
  unsigned char num1_is_greater_than_num2;
  int greater_number;

  num1_is_greater_than_num2 = 0; // initialize to FALSE
  if ((num1 != NULL) && (num2 != NULL))
  {
    if ((num1->left_of_decimal != NULL) && (num2->left_of_decimal != NULL))
    {
      greater_number = packed_string_integer_determine_absolute_value_larger_of_two_integers (num1, num2);
      switch (greater_number)
      {
        case 1: // |num1| > |num2|.
          switch (num1->sign)
          {
            case positive: // num1 is positive
              switch (num2->sign)
              {
                case positive: // |num1| > |num2|. Since num1 is positive and num2 is positive, num1 > num2.
                  num1_is_greater_than_num2 = TRUE;
                break;
                case zero:     // |num1| > |num2|. Since num1 is positive and num2 is zero, num1 > num2.
                  num1_is_greater_than_num2 = TRUE;
                break;
                case negative: // |num1| > |num2|. Since num1 is positive and num2 is negative, num1 > num2.
                  num1_is_greater_than_num2 = TRUE;
                break;
                case undefined:
                break;
                default:
                break;
              }
            break;
            case zero: // num1 is zero
              switch (num2->sign)
              {
                case positive: // |num1| > |num2|. I do not know how num1 can be greater than num2 and yet num1 is zero while num2 is positive. Regardless, set result to num1 < num2.
                  num1_is_greater_than_num2 = FALSE;
                break;
                case zero:     // |num1| > |num2|. I do not know how num1 can be greater than num2 yet num1 equals zero and num2 equals zero. Regardless, set result to num1 < num2.
                  num1_is_greater_than_num2 = FALSE;
                break;
                case negative: // |num1| > |num2|. Since num1 is zero and num2 is negative, num1 > num2.
                  num1_is_greater_than_num2 = TRUE;
                break;
                case undefined:
                break;
                default:
                break;
              }
            break;
            case negative: // num1 is negative
              switch (num2->sign)
              {
                case positive: // |num1| > |num2|. Since num1 is negative and num2 is positive, num1 < num2.
                  num1_is_greater_than_num2 = FALSE;
                break;
                case zero:     // |num1| > |num2|. Since num1 is negative and num2 is zero, num1 < num2.
                  num1_is_greater_than_num2 = FALSE;
                break;
                case negative: // |num1| > |num2|. Since num1 is negative and num2 is negative, num1 < num2 
                  num1_is_greater_than_num2 = FALSE;
                break;
                case undefined:
                break;
                default:
                break;
              }
            break;
            case undefined:
            break;
            default:
            break;
          }
        break;
        case 0: // |num1| == |num2|
          switch (num1->sign)
          {
            case positive:
              switch (num2->sign)
              {
                case positive:  // |num1| == |num2|. Since num1 is positive and num2 is positive, num1 == num2
                  num1_is_greater_than_num2 = FALSE;
                break;
                case zero:     // |num1| == |num2|. I do not know how num1 and num2 can be equal since num1 is positive and num2 is zero. Regardless, set result to num1 < num2
                  num1_is_greater_than_num2 = FALSE;
                break;
                case negative: // |num1| == |num2|. Since num1 is positive and num2 is negative, num1 > num2 
                  num1_is_greater_than_num2 = TRUE;
                break;
                case undefined:
                break;
                default:
                break;
              }
            break;
            case zero:
              switch (num2->sign)
              {
                case positive: // |num1| == |num2|. Since num1 is zero and num2 is positive, num1 == num2
                  num1_is_greater_than_num2 = FALSE;
                break;
                case zero:    // |num1| == |num2|. Since num1 is zero and num2 is zero, num1 == num2
                  num1_is_greater_than_num2 = FALSE;
                break;
                case negative: // |num1| == |num2|. I do not know how num1 and num2 can be equal since num1 is zero and num2 is negative. Regardless, set result to num1 < num2
                  num1_is_greater_than_num2 = FALSE;
                break;
                case undefined:
                break;
                default:
                break;
              }
            break;
            case negative:
              switch (num2->sign)
              {
                case positive: // |num1| == |num2|. Since num1 is negative and num2 is positive,  num1 < num2
                  num1_is_greater_than_num2 = FALSE;
                break;
                case zero:     // |num1| == |num2|. Since num1 is negative and num2 is zero, num1 < num2
                  num1_is_greater_than_num2 = FALSE;
                break;
                case negative: // |num1| == |num2|. Since num1 is negative and num2 is negative, num1 == num2
                  num1_is_greater_than_num2 = FALSE;
                break;
                case undefined:
                break;
                default:
                break;
              }
            break;
            case undefined:
            break;
            default:
            break;
          }
        break;
        case -1: // num1 < num2
          switch (num1->sign)
          {
            case positive: // num1 is positive
              switch (num2->sign)
              {
                case positive: // |num1| < |num2|. Since num1 is positive and num2 is positive, num1 < num2
                  num1_is_greater_than_num2 = FALSE;
                break;
                case zero:     // |num1| < |num2|. Since num1 is positive and num2 is zero, num1 < num2
                  num1_is_greater_than_num2 = FALSE;
                break;
                case negative: // |num1| < |num2|. Since num1 is positive and num2 is negative, num1 > num2
                  num1_is_greater_than_num2 = TRUE;
                break;
                case undefined:
                break;
                default:
                break;
              }
            break;
            case zero: // num1 is zero
              switch (num2->sign)
              {
                case positive: // |num1| < |num2|. Since num1 is zero and num2 is positive, num1 < num2
                  num1_is_greater_than_num2 = FALSE;
                break;
                case zero:     // |num1| < |num2|. I do not know how num1 can be greater than num2 yet num1 equals zero and num2 equals zero. Regardless, set result to num1 < num2
                  num1_is_greater_than_num2 = FALSE;
                break;
                case negative: // |num1| < |num2|. Since num1 is zero and num2 is negative, num1 > num2
                  num1_is_greater_than_num2 = TRUE;
                break;
                case undefined:
                break;
                default:
                break;
              }
            break;
            case negative: // num1 is negative
              switch (num2->sign)
              {
                case positive: // |num1| < |num2|. Since num1 is negative and num2 is positive, num1 < num2
                  num1_is_greater_than_num2 = FALSE;
                break;
                case zero:     // |num1| == |num2|. Since num1 is negative and num2 is zero, num1 < num2
                  num1_is_greater_than_num2 = FALSE;
                break;
                case negative: // |num1| < |num2|.  Since num1 and num2 are both negative, num1 > num2
                  num1_is_greater_than_num2 = TRUE;
                break;
                case undefined:
                break;
                default:
                break;
              }
            break;
            case undefined:
            break;
            default:
            break;
          }
        break;
        default:
        break;
      }
    }
    else
    {
// ***********************************************************************************
// * If num2 is zero, its LEFT_OF_DECIMAL component is NULL.                         *
// *                                                                                 *
// * WARNING: num2 could also be undefined if its LEFT_OF_DECIMAL component is NULL. *
// ***********************************************************************************
      if ((num1->left_of_decimal != NULL) && (num2->left_of_decimal == NULL))
      {
        switch (num1->sign)
        {
          case positive: // Since num1 is positive and num2 is zero, num1 > num2
            if (num2->sign == zero)
            {
              num1_is_greater_than_num2 = TRUE;
            }
          break;
          case zero: // Weird state! num1 LEFT OF DECIMAL is not NULL yet num1 is zero?! This is not normal and should not occur. Regardless, presume num1 is indeed zero.
            if (num2->sign == zero)
            {
              num1_is_greater_than_num2 = FALSE;
            }
          break;
          case negative: // Since num1 is negative and num2 is zero, num1 < num2
            if (num2->sign == zero)
            {
              num1_is_greater_than_num2 = FALSE;
            }
          break;
          case undefined:
          break;
          default:
          break;
        }
      }
      else
      {
// ***********************************************************************************
// * If num1 is zero, its LEFT_OF_DECIMAL component is NULL.                         *
// *                                                                                 *
// * WARNING: num2 could also be undefined if its LEFT_OF_DECIMAL component is NULL. *
// ***********************************************************************************
        if ((num1->left_of_decimal == NULL) && (num2->left_of_decimal != NULL))
        {
          switch (num2->sign)
          {
            case positive:
              if (num1->sign == zero)
              {
                num1_is_greater_than_num2 = FALSE; // Since num2 is positive and num1 is zero, num1 < num2
              }
            break;
            case zero: // Weird state! num2 LEFT OF DECIMAL is not NULL yet num2 is zero?! This is not normal and should not occur. Regardless, presume num2 is indeed zero.
              if (num1->sign == zero)
              {
                num1_is_greater_than_num2 = FALSE;
              }
            break;
            case negative: // Since num2 is negative and num1 is zero, num1 > num2
              if (num1->sign == zero)
              {
                num1_is_greater_than_num2 = TRUE;
              }
            break;
            case undefined:
            break;
            default:
            break;
          }
        }
        else
        {
          if ((num1->left_of_decimal == NULL) && (num2->left_of_decimal == NULL))
          {
            if ((num1->sign == zero) && (num2->sign == zero))
            {
              num1_is_greater_than_num2 = FALSE;
            }
          }
        }
      }

    }
  }
  return num1_is_greater_than_num2;
}




// **********************************************************
// * packed_string_integer_greater_than_or_equal            *
// *                                                        *
// * This library determiness if num1 is greater than num2. *
// *                                                        *
// * If num1 >= num2 return 1 (TRUE)                        *
// * If num1 <= num2 return 0 (FALSE)                       *
// *                                                        *
// * If an error occurs, 0 (FALSE) is returned.             *
// **********************************************************
unsigned char packed_string_integer_greater_than_or_equal (psint *num1, psint *num2)
{
  unsigned char num1_is_greater_than_or_equal_num2;
  int greater_number;

  num1_is_greater_than_or_equal_num2 = 0; // initialize to FALSE
  if ((num1 != NULL) && (num2 != NULL))
  {
    if ((num1->left_of_decimal != NULL) && (num2->left_of_decimal != NULL))
    {
      greater_number = packed_string_integer_determine_absolute_value_larger_of_two_integers (num1, num2);
      switch (greater_number)
      {
        case 1: // |num1| > |num2|.
          switch (num1->sign)
          {
            case positive: // num1 is positive
              switch (num2->sign)
              {
                case positive: // |num1| > |num2|. Since num1 is positive and num2 is positive, num1 > num2.
                  num1_is_greater_than_or_equal_num2 = TRUE;
                break;
                case zero:     // |num1| > |num2|. Since num1 is positive and num2 is zero, num1 > num2.
                  num1_is_greater_than_or_equal_num2 = TRUE;
                break;
                case negative: // |num1| > |num2|. Since num1 is positive and num2 is negative, num1 > num2.
                  num1_is_greater_than_or_equal_num2 = TRUE;
                break;
                default:
                break;
              }
            break;
            case zero: // num1 is zero
              switch (num2->sign)
              {
                case positive: // |num1| > |num2|. I do not know how num1 can be greater than num2 and yet num1 is zero while num2 is positive. Regardless, set result to num1 < num2.
                  num1_is_greater_than_or_equal_num2 = FALSE;
                break;
                case zero:     // |num1| > |num2|. I do not know how num1 can be greater than num2 yet num1 equals zero and num2 equals zero. Regardless, set result to num1 < num2.
                  num1_is_greater_than_or_equal_num2 = FALSE;
                break;
                case negative: // |num1| > |num2|. Since num1 is zero and num2 is negative, num1 > num2.
                  num1_is_greater_than_or_equal_num2 = TRUE;
                break;
                default:
                break;
              }
            break;
            case negative: // num1 is negative
              switch (num2->sign)
              {
                case positive: // |num1| > |num2|. Since num1 is negative and num2 is positive, num1 < num2.
                  num1_is_greater_than_or_equal_num2 = FALSE;
                break;
                case zero:     // |num1| > |num2|. Since num1 is negative and num2 is zero, num1 < num2.
                  num1_is_greater_than_or_equal_num2 = FALSE;
                break;
                case negative: // |num1| > |num2|. Since num1 is negative and num2 is negative, num1 < num2 
                  num1_is_greater_than_or_equal_num2 = FALSE;
                break;
                default:
                break;
              }
            break;
            case undefined:
            break;
            default:
            break;
          }
        break;
        case 0: // |num1| == |num2|
          switch (num1->sign)
          {
            case positive:
              switch (num2->sign)
              {
                case positive:  // |num1| == |num2|. Since num1 is positive and num2 is positive, num1 == num2
                  num1_is_greater_than_or_equal_num2 = TRUE;
                break;
                case zero:     // |num1| == |num2|. I do not know how num1 and num2 can be equal since num1 is positive and num2 is zero. Regardless, set result to num1 < num2
                  num1_is_greater_than_or_equal_num2 = FALSE;
                break;
                case negative: // |num1| == |num2|. Since num1 is positive and num2 is negative, num1 > num2 
                  num1_is_greater_than_or_equal_num2 = TRUE;
                break;
                case undefined:
                break;
                default:
                break;
              }
            break;
            case zero:
              switch (num2->sign)
              {
                case positive: // |num1| == |num2|. Since num1 is zero and num2 is positive, set result to num1 < num2
                  num1_is_greater_than_or_equal_num2 = FALSE;
                break;
                case zero:    // |num1| == |num2|. Since num1 is zero and num2 is zero, num1 == num2
                  num1_is_greater_than_or_equal_num2 = TRUE;
                break;
                case negative: // |num1| == |num2|. I do not know how num1 and num2 can be equal since num1 is zero and num2 is negative. Regardless, set result to num1 < num2
                  num1_is_greater_than_or_equal_num2 = FALSE;
                break;
                case undefined:
                break;
                default:
                break;
              }
            break;
            case negative:
              switch (num2->sign)
              {
                case positive: // |num1| == |num2|. Since num1 is negative and num2 is positive,  num1 < num2
                  num1_is_greater_than_or_equal_num2 = FALSE;
                break;
                case zero:     // |num1| == |num2|. Since num1 is negative and num2 is zero, num1 < num2
                  num1_is_greater_than_or_equal_num2 = FALSE;
                break;
                case negative: // |num1| == |num2|. Since num1 is negative and num2 is negative, num1 == num2
                  num1_is_greater_than_or_equal_num2 = TRUE;
                break;
                case undefined:
                break;
                default:
                break;
              }
            break;
            case undefined:
            break;
            default:
            break;
          }
        break;
        case -1: // num1 < num2
          switch (num1->sign)
          {
            case positive: // num1 is positive
              switch (num2->sign)
              {
                case positive: // |num1| < |num2|. Since num1 is positive and num2 is positive, num1 < num2
                  num1_is_greater_than_or_equal_num2 = FALSE;
                break;
                case zero:     // |num1| < |num2|. Since num1 is positive and num2 is zero, num1 < num2
                  num1_is_greater_than_or_equal_num2 = FALSE;
                break;
                case negative: // |num1| < |num2|. Since num1 is positive and num2 is negative, num1 > num2
                  num1_is_greater_than_or_equal_num2 = TRUE;
                break;
                case undefined:
                break;
                default:
                break;
              }
            break;
            case zero: // num1 is zero
              switch (num2->sign)
              {
                case positive: // |num1| < |num2|. Since num1 is zero and num2 is positive, num1 < num2
                  num1_is_greater_than_or_equal_num2 = FALSE;
                break;
                case zero:     // |num1| < |num2|. I do not know how num1 can be greater than num2 yet num1 equals zero and num2 equals zero. Regardless, set result to num1 < num2
                  num1_is_greater_than_or_equal_num2 = FALSE;
                break;
                case negative: // |num1| < |num2|. Since num1 is zero and num2 is negative, num1 > num2
                  num1_is_greater_than_or_equal_num2 = TRUE;
                break;
                case undefined:
                break;
                default:
                break;
              }
            break;
            case negative: // num1 is negative
              switch (num2->sign)
              {
                case positive: // |num1| < |num2|. Since num1 is negative and num2 is positive, num1 < num2
                  num1_is_greater_than_or_equal_num2 = FALSE;
                break;
                case zero:     // |num1| < |num2|. Since num1 is negative and num2 is zero, num1 < num2
                  num1_is_greater_than_or_equal_num2 = FALSE;
                break;
                case negative: // |num1| < |num2|.  Since num1 and num2 are both negative, num1 > num2
                  num1_is_greater_than_or_equal_num2 = TRUE;
                break;
                case undefined:
                break;
                default:
                break;
              }
            break;
            case undefined:
            break;
            default:
            break;
          }
        break;
        case undefined:
        break;
        default:
        break;
      }
    }
    else
    {
// ***********************************************************************************
// * If num2 is zero, its LEFT_OF_DECIMAL component is NULL.                         *
// *                                                                                 *
// * WARNING: num2 could also be undefined if its LEFT_OF_DECIMAL component is NULL. *
// ***********************************************************************************
      if ((num1->left_of_decimal != NULL) && (num2->left_of_decimal == NULL))
      {
        switch (num1->sign)
        {
          case positive:
            if (num2->sign == zero)
            {
              num1_is_greater_than_or_equal_num2 = TRUE; // Since num1 is positive and num2 is zero, num1 > num2
            }
          break;
          case zero: // Weird state! num1 LEFT OF DECIMAL is not NULL yet num1 is zero?! This is not normal and should not occur. Regardless, presume num1 is indeed zero.
            if (num2->sign == zero)
            {
              num1_is_greater_than_or_equal_num2 = TRUE;
            }
          break;
          case negative:
            if (num2->sign == zero)
            {
              num1_is_greater_than_or_equal_num2 = FALSE; // Since num1 is negative and num2 is zero, num1 < num2
            }
          break;
          case undefined:
          break;
          default:
          break;
        }
      }
      else
      {
// ***********************************************************************************
// * If num1 is zero, its LEFT_OF_DECIMAL component is NULL.                         *
// *                                                                                 *
// * WARNING: num1 could also be undefined if its LEFT_OF_DECIMAL component is NULL. *
// ***********************************************************************************
        if ((num1->left_of_decimal == NULL) && (num2->left_of_decimal != NULL))
        {
          switch (num2->sign)
          {
            case positive: // Since num2 is positive and num1 is zero, num1 < num2
              if (num1->sign == zero)
              {
                num1_is_greater_than_or_equal_num2 = FALSE;
              }
            break;
            case zero: // Weird state! num2 LEFT OF DECIMAL is not NULL yet num2 is zero?! This is not normal and should not occur. Regardless, presume num2 is indeed zero.
              if (num1->sign == zero)
              {
                num1_is_greater_than_or_equal_num2 = TRUE;
              }
            break;
            case negative: // Since num2 is negative and num1 is zero, num1 > num2
              if (num1->sign == zero)
              {
                num1_is_greater_than_or_equal_num2 = TRUE;
              }
            break;
            case undefined:
            break;
            default:
            break;
          }
        }
        else
        {
          if ((num1->left_of_decimal == NULL) && (num2->left_of_decimal == NULL))
          {
            if ((num1->sign == zero) && (num2->sign == zero))
            {
              num1_is_greater_than_or_equal_num2 = TRUE;
            }
          }
        }
      }
    }
  }
  return num1_is_greater_than_or_equal_num2;
}




// ***************************************************************************************************************
// * packed_string_integer_less_than                                                                             *
// *                                                                                                             *
// * This library determiness if packed string-based integer num1 is less than packed string-based integer num2. *
// *                                                                                                             *
// * If num1 <  num2 return 1 (TRUE)                                                                             *
// * If num1 >= num2 return 0 (FALSE)                                                                            *
// *                                                                                                             *
// * If an error occurs, 0 (FALSE) is returned.                                                                  *
// ***************************************************************************************************************
unsigned char packed_string_integer_less_than (psint *num1, psint *num2)
{
  unsigned char num1_is_less_than_num2;
  int greater_number;

  num1_is_less_than_num2 = 0; // initialize to FALSE
  if ((num1 != NULL) && (num2 != NULL))
  {
    if ((num1->left_of_decimal != NULL) && (num2->left_of_decimal != NULL))
    {
      greater_number = packed_string_integer_determine_absolute_value_larger_of_two_integers (num1, num2);
      switch (greater_number)
      {
        case 1: // |num1| > |num2|.
          switch (num1->sign)
          {
            case positive: // num1 is positive
              switch (num2->sign)
              {
                case positive: // |num1| > |num2|. Since num1 is positive and num2 is positive, num1 > num2.
                  num1_is_less_than_num2 = FALSE;
                break;
                case zero:     // |num1| > |num2|. Since num1 is positive and num2 is zero, num1 > num2.
                  num1_is_less_than_num2 = FALSE;
                break;
                case negative: // |num1| > |num2|. Since num1 is positive and num2 is negative, num1 > num2.
                  num1_is_less_than_num2 = FALSE;
                break;
                case undefined:
                break;
                default:
                break;
              }
            break;
            case zero: // num1 is zero
              switch (num2->sign)
              {
                case positive: // |num1| > |num2|. I do not know how num1 can be greater than num2 and yet num1 is zero while num2 is positive. Regardless, return FALSE
                  num1_is_less_than_num2 = FALSE;
                break;
                case zero:     // |num1| > |num2|. I do not know how num1 can be greater than num2 yet num1 equals zero and num2 equals zero. Regardless, return FALSE
                  num1_is_less_than_num2 = FALSE;
                break;
                case negative: // |num1| > |num2|. Since num1 is zero and num2 is negative, num1 > num2.
                  num1_is_less_than_num2 = FALSE;
                break;
                case undefined:
                break;
                default:
                break;
              }
            break;
            case negative: // num1 is negative
              switch (num2->sign)
              {
                case positive: // |num1| > |num2|. Since num1 is negative and num2 is positive, num1 < num2.
                  num1_is_less_than_num2 = TRUE;
                break;
                case zero:     // |num1| > |num2|. Since num1 is negative and num2 is zero, num1 < num2.
                  num1_is_less_than_num2 = TRUE;
                break;
                case negative: // |num1| > |num2|. Since num1 is negative and num2 is negative, num1 < num2 
                  num1_is_less_than_num2 = TRUE;
                break;
                case undefined:
                break;
                default:
                break;
              }
            break;
            case undefined:
            break;
          }
        break;
        case 0: // |num1| == |num2|
          switch (num1->sign)
          {
            case positive:
              switch (num2->sign)
              {
                case positive:  // |num1| == |num2|. Since num1 is positive and num2 is positive, num1 == num2
                  num1_is_less_than_num2 = FALSE;
                break;
                case zero:     // |num1| == |num2|. I do not know how num1 and num2 can be equal since num1 is positive and num2 is zero. Regardless, return FALSE
                  num1_is_less_than_num2 = FALSE;
                break;
                case negative: // |num1| == |num2|. Since num1 is positive and num2 is negative, num1 > num2 
                  num1_is_less_than_num2 = FALSE;
                break;
                case undefined:
                break;
                default:
                break;
              }
            break;
            case zero:
              switch (num2->sign)
              {
                case positive: // |num1| == |num2|. Since num1 is zero and num2 is positive, num1 == num2
                  num1_is_less_than_num2 = FALSE;
                break;
                case zero:    // |num1| == |num2|. Since num1 is zero and num2 is zero, num1 == num2
                  num1_is_less_than_num2 = FALSE;
                break;
                case negative: // |num1| == |num2|. I do not know how num1 and num2 can be equal since num1 is zero and num2 is negative. Regardless, return FALSE
                  num1_is_less_than_num2 = FALSE;
                break;
                case undefined:
                break;
                default:
                break;
              }
            break;
            case negative:
              switch (num2->sign)
              {
                case positive: // |num1| == |num2|. Since num1 is negative and num2 is positive,  num1 < num2
                  num1_is_less_than_num2 = TRUE;
                break;
                case zero:     // |num1| == |num2|. Since num1 is negative and num2 is zero, num1 < num2
                  num1_is_less_than_num2 = TRUE;
                break;
                case negative: // |num1| == |num2|. Since num1 is negative and num2 is negative, num1 == num2
                  num1_is_less_than_num2 = FALSE;
                break;
                case undefined:
                break;
                default:
                break;
              }
            break;
            case undefined:
            break;
            default:
            break;
          }
        break;
        case -1: // num1 < num2
          switch (num1->sign)
          {
            case positive: // num1 is positive
              switch (num2->sign)
              {
                case positive: // |num1| < |num2|. Since num1 is positive and num2 is positive, num1 < num2
                  num1_is_less_than_num2 = TRUE;
                break;
                case zero:     // |num1| < |num2|. Since num1 is positive and num2 is zero, num1 < num2
                  num1_is_less_than_num2 = TRUE;
                break;
                case negative: // |num1| < |num2|. Since num1 is positive and num2 is negative, num1 > num2
                  num1_is_less_than_num2 = FALSE;
                break;
                case undefined:
                break;
                default:
                break;
              }
            break;
            case zero: // num1 is zero
              switch (num2->sign)
              {
                case positive: // |num1| < |num2|. Since num1 is zero and num2 is positive, num1 < num2
                  num1_is_less_than_num2 = TRUE;
                break;
                case zero:     // |num1| < |num2|. I do not know how num1 can be greater than num2 yet num1 equals zero and num2 equals zero. Regardless, return FALSE
                  num1_is_less_than_num2 = FALSE;
                break;
                case negative: // |num1| < |num2|. Since num1 is zero and num2 is negative, num1 > num2
                  num1_is_less_than_num2 = FALSE;
                break;
                case undefined:
                break;
                default:
                break;
              }
            break;
            case negative: // num1 is negative
              switch (num2->sign)
              {
                case positive: // |num1| < |num2|. Since num1 is negative and num2 is positive, num1 < num2
                  num1_is_less_than_num2 = TRUE;
                break;
                case zero:     // |num1| == |num2|. Since num1 is negative and num2 is zero, num1 < num2
                  num1_is_less_than_num2 = TRUE;
                break;
                case negative: // |num1| < |num2|.  Since num1 and num2 are both negative, num1 > num2
                  num1_is_less_than_num2 = FALSE;
                break;
                case undefined:
                break;
                default:
                break;
              }
            break;
            case undefined:
            break;
            default:
            break;
          }
        break;
        case undefined:
        break;
        default:
        break;
      }
    }
    else
    {
// ***********************************************************************************
// * If num2 is zero, its LEFT_OF_DECIMAL component is NULL.                         *
// *                                                                                 *
// * WARNING: num2 could also be undefined if its LEFT_OF_DECIMAL component is NULL. *
// ***********************************************************************************
      if ((num1->left_of_decimal != NULL) && (num2->left_of_decimal == NULL))
      {
        switch (num1->sign)
        {
          case positive: // Since num1 is positive and num2 is zero, num1 > num2
            if (num2->sign == zero)
            {
              num1_is_less_than_num2 = FALSE;
            }
          break;
          case zero: // Weird state! num1 LEFT OF DECIMAL is not NULL yet num1 is zero?! This is not normal and should not occur. Regardless, presume num1 is indeed zero.
            if (num2->sign == zero)
            {
              num1_is_less_than_num2 = FALSE;
            }
          break;
          case negative: // Since num1 is negative and num2 is zero, num1 < num2
            if (num2->sign == zero)
            {
              num1_is_less_than_num2 = TRUE;
            }
          break;
          case undefined:
          break;
          default:
          break;
        }
      }
      else
      {
// ***********************************************************************************
// * If num1 is zero, its LEFT_OF_DECIMAL component is NULL.                         *
// *                                                                                 *
// * WARNING: num1 could also be undefined if its LEFT_OF_DECIMAL component is NULL. *
// ***********************************************************************************
        if ((num1->left_of_decimal == NULL) && (num2->left_of_decimal != NULL))
        {
          switch (num2->sign)
          {
            case positive: // Since num2 is positive and num1 is zero, num1 < num2
              if (num1->sign == zero)
              {
                num1_is_less_than_num2 = TRUE;
              }
            break;
            case zero: // Weird state! num2 LEFT OF DECIMAL is not NULL yet num2 is zero?! This is not normal and should not occur. Regardless, presume num2 is indeed zero.
              if (num1->sign == zero)
              {
                num1_is_less_than_num2 = FALSE;
              }
            break;
            case negative: // Since num2 is negative and num1 is zero, num1 > num2
              if (num1->sign == zero)
              {
                num1_is_less_than_num2 = FALSE;
              }
            break;
            case undefined:
            break;
            default:
            break;
          }
        }
        else
        {
          if ((num1->left_of_decimal == NULL) && (num2->left_of_decimal == NULL))
          {
            if ((num1->sign == zero) && (num2->sign == zero))
            {
              num1_is_less_than_num2 = FALSE;
            }
          }
        }
      }
    }
  }
  return num1_is_less_than_num2;
}




// ***************************************************************************************************************************
// * packed_string_integer_less_than_or_equal                                                                                *
// *                                                                                                                         *
// * This library determiness if packed string-based integer num1 is less than or equal to packed string-based integer num2. *
// *                                                                                                                         *
// * If num1 <= num2 return 1 (TRUE)                                                                                         *
// * If num1 > num2 return 0 (FALSE)                                                                                         *
// *                                                                                                                         *
// * If an error occurs, 0 (FALSE) is returned.                                                                              *
// ***************************************************************************************************************************
unsigned char packed_string_integer_less_than_or_equal (psint *num1, psint *num2)
{
  unsigned char num1_is_less_than_or_equal_num2;
  int greater_number;

  num1_is_less_than_or_equal_num2 = FALSE;
  if ((num1 != NULL) && (num2 != NULL))
  {
    if ((num1->left_of_decimal != NULL) && (num2->left_of_decimal != NULL))
    {
      greater_number = packed_string_integer_determine_absolute_value_larger_of_two_integers (num1, num2);
      switch (greater_number)
      {
        case 1: // |num1| > |num2|.
          switch (num1->sign)
          {
            case positive: // num1 is positive
              switch (num2->sign)
              {
                case positive: // |num1| > |num2|. Since num1 is positive and num2 is positive, num1 > num2.
                  num1_is_less_than_or_equal_num2 = FALSE;
                break;
                case zero:     // |num1| > |num2|. Since num1 is positive and num2 is zero, num1 > num2.
                  num1_is_less_than_or_equal_num2 = FALSE;
                break;
                case negative: // |num1| > |num2|. Since num1 is positive and num2 is negative, num1 > num2.
                  num1_is_less_than_or_equal_num2 = FALSE;
                break;
                default:
                break;
              }
            break;
            case zero: // num1 is zero
              switch (num2->sign)
              {
                case positive: // |num1| > |num2|. I do not know how num1 can be greater than num2 and yet num1 is zero while num2 is positive. Regardless, return FALSE.
                  num1_is_less_than_or_equal_num2 = FALSE;
                break;
                case zero:     // |num1| > |num2|. I do not know how num1 can be greater than num2 yet num1 equals zero and num2 equals zero. Regardless, return FALSE.
                  num1_is_less_than_or_equal_num2 = FALSE;
                break;
                case negative: // |num1| > |num2|. Since num1 is zero and num2 is negative, num1 > num2.
                  num1_is_less_than_or_equal_num2 = FALSE;
                break;
                default:
                break;
              }
            break;
            case negative: // num1 is negative
              switch (num2->sign)
              {
                case positive: // |num1| > |num2|. Since num1 is negative and num2 is positive, num1 < num2.
                  num1_is_less_than_or_equal_num2 = TRUE;
                break;
                case zero:     // |num1| > |num2|. Since num1 is negative and num2 is zero, num1 < num2.
                  num1_is_less_than_or_equal_num2 = TRUE;
                break;
                case negative: // |num1| > |num2|. Since num1 is negative and num2 is negative, num1 < num2 
                  num1_is_less_than_or_equal_num2 = TRUE;
                break;
                default:
                break;
              }
            break;
            case undefined:
            break;
            default:
            break;
          }
        break;
        case 0: // |num1| == |num2|
          switch (num1->sign)
          {
            case positive:
              switch (num2->sign)
              {
                case positive:  // |num1| == |num2|. Since num1 is positive and num2 is positive, num1 == num2
                  num1_is_less_than_or_equal_num2 = TRUE;
                break;
                case zero:     // |num1| == |num2|. I do not know how num1 and num2 can be equal since num1 is positive and num2 is zero. Regardless, return FALSE.
                  num1_is_less_than_or_equal_num2 = FALSE;
                break;
                case negative: // |num1| == |num2|. Since num1 is positive and num2 is negative, num1 > num2 
                  num1_is_less_than_or_equal_num2 = TRUE;
                break;
                case undefined:
                break;
                default:
                break;
              }
            break;
            case zero:
              switch (num2->sign)
              {
                case positive: // |num1| == |num2|. Since num1 is zero and num2 is positive, num1 < num2
                  num1_is_less_than_or_equal_num2 = TRUE;
                break;
                case zero:    // |num1| == |num2|. Since num1 is zero and num2 is zero, num1 == num2
                  num1_is_less_than_or_equal_num2 = TRUE;
                break;
                case negative: // |num1| == |num2|. I do not know how num1 and num2 can be equal since num1 is zero and num2 is negative. Regardless, return FALSE.
                  num1_is_less_than_or_equal_num2 = FALSE;
                break;
                case undefined:
                break;
                default:
                break;
              }
            break;
            case negative:
              switch (num2->sign)
              {
                case positive: // |num1| == |num2|. Since num1 is negative and num2 is positive,  num1 < num2
                  num1_is_less_than_or_equal_num2 = TRUE;
                break;
                case zero:     // |num1| == |num2|. Since num1 is negative and num2 is zero, num1 < num2
                  num1_is_less_than_or_equal_num2 = TRUE;
                break;
                case negative: // |num1| == |num2|. Since num1 is negative and num2 is negative, num1 == num2
                  num1_is_less_than_or_equal_num2 = TRUE;
                break;
                case undefined:
                break;
                default:
                break;
              }
            break;
            case undefined:
            break;
          }
        break;
        case -1: // num1 < num2
          switch (num1->sign)
          {
            case positive: // num1 is positive
              switch (num2->sign)
              {
                case positive: // |num1| < |num2|. Since num1 is positive and num2 is positive, num1 < num2
                  num1_is_less_than_or_equal_num2 = TRUE;
                break;
                case zero:     // |num1| < |num2|. Since num1 is positive and num2 is zero, num1 < num2
                  num1_is_less_than_or_equal_num2 = TRUE;
                break;
                case negative: // |num1| < |num2|. Since num1 is positive and num2 is negative, num1 > num2
                  num1_is_less_than_or_equal_num2 = FALSE;
                break;
                case undefined:
                break;
                default:
                break;
              }
            break;
            case zero: // num1 is zero
              switch (num2->sign)
              {
                case positive: // |num1| < |num2|. Since num1 is zero and num2 is positive, num1 < num2
                  num1_is_less_than_or_equal_num2 = TRUE;
                break;
                case zero:     // |num1| < |num2|. I do not know how num1 can be greater than num2 yet num1 equals zero and num2 equals zero. Regardless, return FALSE.
                  num1_is_less_than_or_equal_num2 = FALSE;
                break;
                case negative: // |num1| < |num2|. Since num1 is zero and num2 is negative, num1 > num2
                  num1_is_less_than_or_equal_num2 = FALSE;
                break;
                case undefined:
                break;
                default:
                break;
              }
            break;
            case negative: // num1 is negative
              switch (num2->sign)
              {
                case positive: // |num1| < |num2|. Since num1 is negative and num2 is positive, num1 < num2
                  num1_is_less_than_or_equal_num2 = TRUE;
                break;
                case zero:     // |num1| < |num2|. Since num1 is negative and num2 is zero, num1 < num2
                  num1_is_less_than_or_equal_num2 = TRUE;
                break;
                case negative: // |num1| < |num2|.  Since num1 and num2 are both negative, num1 > num2
                  num1_is_less_than_or_equal_num2 = FALSE;
                break;
                case undefined:
                break;
                default:
                break;
              }
            break;
            case undefined:
            break;
            default:
            break;
          }
        break;
        case undefined:
        break;
        default:
        break;
      }
    }
    else
    {
// ***********************************************************************************
// * If num2 is zero, its LEFT_OF_DECIMAL component is NULL.                         *
// *                                                                                 *
// * WARNING: num2 could also be undefined if its LEFT_OF_DECIMAL component is NULL. *
// ***********************************************************************************
      if ((num1->left_of_decimal != NULL) && (num2->left_of_decimal == NULL))
      {
        switch (num1->sign)
        {
          case positive:
            if (num2->sign == zero)
            {
              num1_is_less_than_or_equal_num2 = FALSE; // Since num1 is positive and num2 is zero, num1 > num2
            }
          break;
          case zero: // Weird state! num1 LEFT OF DECIMAL is not NULL yet num1 is zero?! This is not normal and should not occur. Regardless, presume num1 is indeed zero.
            if (num2->sign == zero)
            {
              num1_is_less_than_or_equal_num2 = TRUE;
            }
          break;
          case negative:
            if (num2->sign == zero)
            {
              num1_is_less_than_or_equal_num2 = TRUE; // Since num1 is negative and num2 is zero, num1 < num2
            }
          break;
          case undefined:
          break;
          default:
          break;
        }
      }
      else
      {
// ***********************************************************************************
// * If num1 is zero, its LEFT_OF_DECIMAL component is NULL.                         *
// *                                                                                 *
// * WARNING: num1 could also be undefined if its LEFT_OF_DECIMAL component is NULL. *
// ***********************************************************************************
        if ((num1->left_of_decimal == NULL) && (num2->left_of_decimal != NULL))
        {
          switch (num2->sign)
          {
            case positive: // Since num2 is positive and num1 is zero, num1 < num2
              if (num1->sign == zero)
              {
                num1_is_less_than_or_equal_num2 = TRUE;
              }
            break;
            case zero: // Weird state! num2 LEFT OF DECIMAL is not NULL yet num2 is zero?! This is not normal and should not occur. Regardless, presume num2 is indeed zero.
              if (num1->sign == zero)
              {
                num1_is_less_than_or_equal_num2 = TRUE;
              }
            break;
            case negative: // Since num2 is negative and num1 is zero, num1 > num2
              if (num1->sign == zero)
              {
                num1_is_less_than_or_equal_num2 = FALSE;
              }
            break;
            case undefined:
            break;
            default:
            break;
          }
        }
        else
        {
          if ((num1->left_of_decimal == NULL) && (num2->left_of_decimal == NULL))
          {
            if ((num1->sign == zero) && (num2->sign == zero))
            {
              num1_is_less_than_or_equal_num2 = TRUE;
            }
          }
        }
      }
    }
  }
  return num1_is_less_than_or_equal_num2;
}




// **************************************************************************************************************
// * packed_string_integer_equal                                                                                *
// *                                                                                                            *
// * This library determiness if packed string-based integer num1 is equal to packed string-based integer num2. *
// *                                                                                                            *
// * If num1 == num2 return 1 (TRUE)                                                                            *
// * If num1 != num2 return 0 (FALSE)                                                                           *
// *                                                                                                            *
// * If an error occurs, 0 (FALSE) is returned.                                                                 *
// **************************************************************************************************************
unsigned char packed_string_integer_equal (psint *num1, psint *num2)
{
  unsigned char num1_equals_num2;
  int greater_number;

  num1_equals_num2 = 0; // initialize to FALSE
  if ((num1 != NULL) && (num2 != NULL))
  {
    if ((num1->left_of_decimal != NULL) && (num2->left_of_decimal != NULL))
    {
      greater_number = packed_string_integer_determine_absolute_value_larger_of_two_integers (num1, num2);
      switch (greater_number)
      {
        case 1: // |num1| > |num2|.
          switch (num1->sign)
          {
            case positive: // num1 is positive
              switch (num2->sign)
              {
                case positive: // |num1| > |num2|. Since num1 is positive and num2 is positive, num1 > num2.
                  num1_equals_num2 = FALSE;
                break;
                case zero:     // |num1| > |num2|. Since num1 is positive and num2 is zero, num1 > num2.
                  num1_equals_num2 = FALSE;
                break;
                case negative: // |num1| > |num2|. Since num1 is positive and num2 is negative, num1 > num2.
                  num1_equals_num2 = FALSE;
                break;
                default:
                break;
              }
            break;
            case zero: // num1 is zero
              switch (num2->sign)
              {
                case positive: // |num1| > |num2|. I do not know how num1 can be greater than num2 and yet num1 is zero while num2 is positive. Regardless, return FALSE.
                  num1_equals_num2 = FALSE;
                break;
                case zero:     // |num1| > |num2|. I do not know how num1 can be greater than num2 yet num1 equals zero and num2 equals zero. Regardless, return FALSE.
                  num1_equals_num2 = FALSE;
                break;
                case negative: // |num1| > |num2|. Since num1 is zero and num2 is negative, num1 > num2.
                  num1_equals_num2 = FALSE;
                break;
                default:
                break;
              }
            break;
            case negative: // num1 is negative
              switch (num2->sign)
              {
                case positive: // |num1| > |num2|. Since num1 is negative and num2 is positive, num1 < num2.
                  num1_equals_num2 = FALSE;
                break;
                case zero:     // |num1| > |num2|. Since num1 is negative and num2 is zero, num1 < num2.
                  num1_equals_num2 = FALSE;
                break;
                case negative: // |num1| > |num2|. Since num1 is negative and num2 is negative, num1 < num2 
                  num1_equals_num2 = FALSE;
                break;
                default:
                break;
              }
            break;
            default:
            break;
          }
        break;
        case 0: // |num1| == |num2|
          switch (num1->sign)
          {
            case positive:
              switch (num2->sign)
              {
                case positive:  // |num1| == |num2|. Since num1 is positive and num2 is positive, num1 == num2
                  num1_equals_num2 = TRUE;
                break;
                case zero:     // |num1| == |num2|. I do not know how num1 and num2 can be equal since num1 is positive and num2 is zero. Regardless, return TRUE.
                  num1_equals_num2 = TRUE;
                break;
                case negative: // |num1| == |num2|. Since num1 is positive and num2 is negative, num1 > num2 
                  num1_equals_num2 = FALSE;
                break;
                default:
                break;
              }
            break;
            case zero:
              switch (num2->sign)
              {
                case positive: // |num1| == |num2|. Since num1 is zero and num2 is positive, num1 < num2
                  num1_equals_num2 = FALSE;
                break;
                case zero:    // |num1| == |num2|. Since num1 is zero and num2 is zero, num1 == num2
                  num1_equals_num2 = TRUE;
                break;
                case negative: // |num1| == |num2|. I do not know how num1 and num2 can be equal since num1 is zero and num2 is negative. Regardless, return FALSE.
                  num1_equals_num2 = FALSE;
                break;
                default:
                break;
              }
            break;
            case negative:
              switch (num2->sign)
              {
                case positive: // |num1| == |num2|. Since num1 is negative and num2 is positive,  num1 < num2
                  num1_equals_num2 = FALSE;
                break;
                case zero:     // |num1| == |num2|. Since num1 is negative and num2 is zero, num1 < num2
                  num1_equals_num2 = FALSE;
                break;
                case negative: // |num1| == |num2|. Since num1 is negative and num2 is negative, num1 == num2
                  num1_equals_num2 = TRUE;
                break;
                default:
                break;
              }
            break;
            default:
            break;
          }
        break;
        case -1: // num1 < num2
          switch (num1->sign)
          {
            case positive: // num1 is positive
              switch (num2->sign)
              {
                case positive: // |num1| < |num2|. Since num1 is positive and num2 is positive, num1 < num2
                  num1_equals_num2 = FALSE;
                break;
                case zero:     // |num1| < |num2|. Since num1 is positive and num2 is zero, num1 < num2
                  num1_equals_num2 = FALSE;
                break;
                case negative: // |num1| < |num2|. Since num1 is positive and num2 is negative, num1 > num2
                  num1_equals_num2 = FALSE;
                break;
                default:
                break;
              }
            break;
            case zero: // num1 is zero
              switch (num2->sign)
              {
                case positive: // |num1| < |num2|. Since num1 is zero and num2 is positive, num1 < num2
                  num1_equals_num2 = FALSE;
                break;
                case zero:     // |num1| < |num2|. I do not know how num1 can be greater than num2 yet num1 equals zero and num2 equals zero. Regardless, return FALSE.
                  num1_equals_num2 = FALSE;
                break;
                case negative: // |num1| < |num2|. Since num1 is zero and num2 is negative, num1 > num2
                  num1_equals_num2 = FALSE;
                break;
                default:
                break;
              }
            break;
            case negative: // num1 is negative
              switch (num2->sign)
              {
                case positive: // |num1| < |num2|. Since num1 is negative and num2 is positive, num1 < num2
                  num1_equals_num2 = FALSE;
                break;
                case zero:     // |num1| < |num2|. Since num1 is negative and num2 is zero, num1 < num2
                  num1_equals_num2 = FALSE;
                break;
                case negative: // |num1| < |num2|.  Since num1 and num2 are both negative, num1 > num2
                  num1_equals_num2 = FALSE;
                break;
                default:
                break;
              }
            break;
            default:
            break;
          }
        break;
        default:
        break;
      }
    }
    else
    {
// ***********************************************************************************
// * If num2 is zero, its LEFT_OF_DECIMAL component is NULL.                         *
// *                                                                                 *
// * WARNING: num2 could also be undefined if its LEFT_OF_DECIMAL component is NULL. *
// ***********************************************************************************
      if ((num1->left_of_decimal != NULL) && (num2->left_of_decimal == NULL))
      {
        switch (num1->sign)
        {
          case positive: // Since num1 is positive and num2 is zero, num1 > num2
            if (num2->sign == zero)
            {
              num1_equals_num2 = FALSE;
            }
          break;
          case zero: // Weird state! num1 LEFT OF DECIMAL is not NULL yet num1 is zero?! This is not normal and should not occur. Regardless, presume num1 is indeed zero.
            if (num2->sign == zero)
            {
              num1_equals_num2 = TRUE;
            }
          break;
          case negative: // Since num1 is negative and num2 is zero, num1 < num2
            if (num2->sign == zero)
            {
              num1_equals_num2 = FALSE;
            }
          break;
          case undefined:
          break;
          default:
          break;
        }
      }
      else
      {
// ***********************************************************************************
// * If num1 is zero, its LEFT_OF_DECIMAL component is NULL.                         *
// *                                                                                 *
// * WARNING: num1 could also be undefined if its LEFT_OF_DECIMAL component is NULL. *
// ***********************************************************************************
        if ((num1->left_of_decimal == NULL) && (num2->left_of_decimal != NULL))
        {
          switch (num2->sign)
          {
            case positive: // Since num2 is positive and num1 is zero, num1 < num2
              if (num1->sign == zero)
              {
                num1_equals_num2 = FALSE; 
              }
            break;
            case zero: // Weird state! num2 LEFT OF DECIMAL is not NULL yet num2 is zero?! This is not normal and should not occur. Regardless, presume num2 is indeed zero.
              if (num1->sign == zero)
              {
                num1_equals_num2 = TRUE;
              }
            break;
            case negative: // Since num2 is negative and num1 is zero, num1 > num2
              if (num1->sign == zero)
              {
                num1_equals_num2 = FALSE;
              }
            break;
            case undefined:
            break;
            default:
            break;
          }
        }
        else
        {
          if ((num1->left_of_decimal == NULL) && (num2->left_of_decimal == NULL))
          {
            if ((num1->sign == zero) && (num2->sign == zero))
            {
              num1_equals_num2 = TRUE;
            }
          }
        }
      }
    }
  }
  return num1_equals_num2;
}




// ******************************************************************************************************************
// * packed_string_integer_not_equal                                                                                *
// *                                                                                                                *
// * This library determiness if packed string-based integer num1 is not equal to packed string-based integer num2. *
// *                                                                                                                *
// * If num1 != num2 return 1 (TRUE)                                                                                *
// * If num1 == num2 return 0 (FALSE)                                                                               *
// *                                                                                                                *
// * If an error occurs, 0 (FALSE) is returned.                                                                     *
// ******************************************************************************************************************
unsigned char packed_string_integer_not_equal (psint *num1, psint *num2)
{
  unsigned char num1_is_not_equal_num2;
  int greater_number;

  num1_is_not_equal_num2 = 0; // initialize to FALSE
  if ((num1 != NULL) && (num2 != NULL))
  {
    if ((num1->left_of_decimal != NULL) && (num2->left_of_decimal != NULL))
    {
      greater_number = packed_string_integer_determine_absolute_value_larger_of_two_integers (num1, num2);
      switch (greater_number)
      {
        case 1: // |num1| > |num2|.
          switch (num1->sign)
          {
            case positive: // num1 is positive
              switch (num2->sign)
              {
                case positive: // |num1| > |num2|. Since num1 is positive and num2 is positive, num1 > num2.
                  num1_is_not_equal_num2 = TRUE;
                break;
                case zero:     // |num1| > |num2|. Since num1 is positive and num2 is zero, num1 > num2.
                  num1_is_not_equal_num2 = TRUE;
                break;
                case negative: // |num1| > |num2|. Since num1 is positive and num2 is negative, num1 > num2.
                  num1_is_not_equal_num2 = TRUE;
                break;
                default:
                break;
              }
            break;
            case zero: // num1 is zero
              switch (num2->sign)
              {
                case positive: // |num1| > |num2|. I do not know how num1 can be greater than num2 and yet num1 is zero while num2 is positive. Regardless, return FALSE.
                  num1_is_not_equal_num2 = FALSE;
                break;
                case zero:     // |num1| > |num2|. I do not know how num1 can be greater than num2 yet num1 equals zero and num2 equals zero. Regardless, return FALSE.
                  num1_is_not_equal_num2 = FALSE;
                break;
                case negative: // |num1| > |num2|. Since num1 is zero and num2 is negative, num1 > num2.
                  num1_is_not_equal_num2 = TRUE;
                break;
                default:
                break;
              }
            break;
            case negative: // num1 is negative
              switch (num2->sign)
              {
                case positive: // |num1| > |num2|. Since num1 is negative and num2 is positive, num1 < num2.
                  num1_is_not_equal_num2 = TRUE;
                break;
                case zero:     // |num1| > |num2|. Since num1 is negative and num2 is zero, num1 < num2.
                  num1_is_not_equal_num2 = TRUE;
                break;
                case negative: // |num1| > |num2|. Since num1 is negative and num2 is negative, num1 < num2 
                  num1_is_not_equal_num2 = TRUE;
                break;
                default:
                break;
              }
            break;
            default:
            break;
          }
        break;
        case 0: // |num1| == |num2|
          switch (num1->sign)
          {
            case positive:
              switch (num2->sign)
              {
                case positive:  // |num1| == |num2|. Since num1 is positive and num2 is positive, num1 == num2
                  num1_is_not_equal_num2 = FALSE;
                break;
                case zero:     // |num1| == |num2|. I do not know how num1 and num2 can be equal since num1 is positive and num2 is zero. Regardless, return FALSE.
                  num1_is_not_equal_num2 = FALSE;
                break;
                case negative: // |num1| == |num2|. Since num1 is positive and num2 is negative, num1 > num2 
                  num1_is_not_equal_num2 = TRUE;
                break;
                default:
                break;
              }
            break;
            case zero:
              switch (num2->sign)
              {
                case positive: // |num1| == |num2|. Since num1 is zero and num2 is positive, num1 < num2
                  num1_is_not_equal_num2 = TRUE;
                break;
                case zero:    // |num1| == |num2|. Since num1 is zero and num2 is zero, num1 == num2
                  num1_is_not_equal_num2 = FALSE;
                break;
                case negative: // |num1| == |num2|. I do not know how num1 and num2 can be equal since num1 is zero and num2 is negative. Regardless, return FALSE.
                  num1_is_not_equal_num2 = FALSE;
                break;
                default:
                break;
              }
            break;
            case negative:
              switch (num2->sign)
              {
                case positive: // |num1| == |num2|. Since num1 is negative and num2 is positive,  num1 < num2
                  num1_is_not_equal_num2 = TRUE;
                break;
                case zero:     // |num1| == |num2|. Since num1 is negative and num2 is zero, num1 < num2
                  num1_is_not_equal_num2 = TRUE;
                break;
                case negative: // |num1| == |num2|. Since num1 is negative and num2 is negative, num1 == num2
                  num1_is_not_equal_num2 = FALSE;
                break;
                default:
                break;
              }
            break;
            default:
            break;
          }
        break;
        case -1: // num1 < num2
          switch (num1->sign)
          {
            case positive: // num1 is positive
              switch (num2->sign)
              {
                case positive: // |num1| < |num2|. Since num1 is positive and num2 is positive, num1 < num2
                  num1_is_not_equal_num2 = TRUE;
                break;
                case zero:     // |num1| < |num2|. Since num1 is positive and num2 is zero, num1 < num2
                  num1_is_not_equal_num2 = TRUE;
                break;
                case negative: // |num1| < |num2|. Since num1 is positive and num2 is negative, num1 > num2
                  num1_is_not_equal_num2 = TRUE;
                break;
                default:
                break;
              }
            break;
            case zero: // num1 is zero
              switch (num2->sign)
              {
                case positive: // |num1| < |num2|. Since num1 is zero and num2 is positive, num1 < num2
                  num1_is_not_equal_num2 = TRUE;
                break;
                case zero:     // |num1| < |num2|. I do not know how num1 can be greater than num2 yet num1 equals zero and num2 equals zero. Regardless, return FALSE.
                  num1_is_not_equal_num2 = FALSE;
                break;
                case negative: // |num1| < |num2|. Since num1 is zero and num2 is negative, num1 > num2
                  num1_is_not_equal_num2 = TRUE;
                break;
                default:
                break;
              }
            break;
            case negative: // num1 is negative
              switch (num2->sign)
              {
                case positive: // |num1| < |num2|. Since num1 is negative and num2 is positive, num1 < num2
                  num1_is_not_equal_num2 = TRUE;
                break;
                case zero:     // |num1| < |num2|. Since num1 is negative and num2 is zero, num1 < num2
                  num1_is_not_equal_num2 = TRUE;
                break;
                case negative: // |num1| < |num2|.  Since num1 and num2 are both negative, num1 > num2
                  num1_is_not_equal_num2 = TRUE;
                break;
                default:
                break;
              }
            break;
            default:
            break;
          }
        break;
        default:
        break;
      }
    }
    else
    {
// ***********************************************************************************
// * If num2 is zero, its LEFT_OF_DECIMAL component is NULL.                         *
// *                                                                                 *
// * WARNING: num2 could also be undefined if its LEFT_OF_DECIMAL component is NULL. *
// ***********************************************************************************
      if ((num1->left_of_decimal != NULL) && (num2->left_of_decimal == NULL))
      {
        switch (num1->sign)
        {
          case positive: // Since num1 is positive and num2 is zero, num1 > num2
            if (num2->sign == zero)
            {
              num1_is_not_equal_num2 = TRUE;
            }
          break;
          case zero: // Weird state! num1 LEFT OF DECIMAL is not NULL yet num1 is zero?! This is not normal and should not occur. Regardless, presume num1 is indeed zero.
            if (num2->sign == zero)
            {
              num1_is_not_equal_num2 = FALSE;
            }
          break;
          case negative: // Since num1 is negative and num2 is zero, num1 < num2
            if (num2->sign == zero)
            {
              num1_is_not_equal_num2 = TRUE;
            }
          break;
          case undefined:
          break;
          default:
          break;
        }
      }
      else
      {
// ***********************************************************************************
// * If num1 is zero, its LEFT_OF_DECIMAL component is NULL.                         *
// *                                                                                 *
// * WARNING: num1 could also be undefined if its LEFT_OF_DECIMAL component is NULL. *
// ***********************************************************************************
        if ((num1->left_of_decimal == NULL) && (num2->left_of_decimal != NULL))
        {
          switch (num2->sign)
          {
            case positive: // Since num2 is positive and num1 is zero, num1 < num2
              if (num1->sign == zero)
              {
                num1_is_not_equal_num2 = TRUE;
              }
            break;
            case zero: // Weird state! num2 LEFT OF DECIMAL is not NULL yet num2 is zero?! This is not normal and should not occur. Regardless, presume num2 is indeed zero.
              if (num1->sign == zero)
              {
                num1_is_not_equal_num2 = FALSE;
              }
            break;
            case negative: // Since num2 is negative and num1 is zero, num1 > num2
              if (num1->sign == zero)
              {
                num1_is_not_equal_num2 = TRUE;
              }
            break;
            case undefined:
            break;
            default:
            break;
          }
        }
        else
        {
          if ((num1->left_of_decimal == NULL) && (num2->left_of_decimal == NULL))
          {
            if ((num1->sign == zero) && (num2->sign == zero))
            {
              num1_is_not_equal_num2 = FALSE;
            }
          }
        }
      }
    }
  }
  return num1_is_not_equal_num2;
}




// **************************************************************************************
// * packed_string_integer_is_divisible_by_two                                          *
// *                                                                                    *
// * A quick check function to determine if a string-based integer is divisible by two. *
// **************************************************************************************
unsigned char packed_string_integer_is_divisible_by_two (psint *number)
{
  unsigned char is_divisible_by_two, packed_byte, nibble_low;

  is_divisible_by_two = FALSE;
  if (number != NULL)
  {
    if (number->left_of_decimal != NULL)
    {
      if ((number->sign == positive) || (number->sign == negative))
      {
        if (number->left_of_decimal->highest_digit_position >= 0)
        {
          packed_byte = number->left_of_decimal->packed_number_block[0];
          nibble_low  = packed_byte & 0x0f;
          switch (nibble_low)
          {
            case 0:
            case 2:
            case 4:
            case 6:
            case 8:
              is_divisible_by_two = TRUE;
            break;
            default:
            break;
          }
        }
      }
    }
    else
    {
      if (number->sign == zero)
      {
        is_divisible_by_two = TRUE;
      }
    }
  }
  return is_divisible_by_two;
}




// ***************************************************************************************
// * packed_string_integer_is_divisible_by_five                                          *
// *                                                                                     *
// * A quick check function to determine if a string-based integer is divisible by five. *
// ***************************************************************************************
unsigned char packed_string_integer_is_divisible_by_five (psint *number)
{
  unsigned char is_divisible_by_five, packed_byte, nibble_low;

  is_divisible_by_five = FALSE;
  if (number != NULL)
  {
    if (number->left_of_decimal != NULL)
    {
      if ((number->sign == positive) || (number->sign == negative))
      {
        if (number->left_of_decimal->highest_digit_position >= 0)
        {
          packed_byte = number->left_of_decimal->packed_number_block[0];
          nibble_low  = packed_byte & 0x0f;
          switch (nibble_low)
          {
            case 0:
            case 5:
              is_divisible_by_five = TRUE;
            break;
            default:
            break;
          }
        }
      }
    }
    else
    {
      if (number->sign == zero)
      {
        is_divisible_by_five = TRUE;
      }
    }
  }
  return is_divisible_by_five;
}




psint * packed_string_integer_shift_digits_left (psint *number, long long int num_times_to_shift_left)
{
  psint *new_shifted_number; 
  psnc *temp_num;
  unsigned char num_packed_byte, num_nibble_low;
  long long int i, counter;

  temp_num           = NULL;
  new_shifted_number = NULL;
  counter = 0;
  if (number != NULL)
  { 
    if (number->left_of_decimal != NULL)
    {
      if ((number->sign == positive) || (number->sign == negative))
      {
        new_shifted_number = (psint *) malloc(sizeof(new_shifted_number));
        if (new_shifted_number != NULL)
        {
          new_shifted_number->sign = number->sign;
          new_shifted_number->status_flag = 0;
          new_shifted_number->left_of_decimal = NULL;
          counter = num_times_to_shift_left;
          if (counter == 0)
          {
            new_shifted_number = packed_string_integer_copy_number (new_shifted_number, number);
          }
          else
          {
            while (counter > 1)
            {
              new_shifted_number = packed_string_integer_append_two_digits (new_shifted_number, 0); // append two zero digits
              counter = counter - 2; // two digits are packed in each byte
            }
            if (counter == 1)
            {
              new_shifted_number = packed_string_integer_append_one_digit (new_shifted_number, 0); // append one zero digit.
            }  
            temp_num = number->left_of_decimal;
            while (temp_num != NULL)
            {
              if ((temp_num->highest_digit_position >= 0) && (temp_num->highest_digit_position < MAX_PACKED_NUMBER_BLOCK_SIZE))
              {
                for (i = 0; i < temp_num->highest_digit_position; i++)
                {
                  num_packed_byte = temp_num->packed_number_block[i];
                  new_shifted_number = packed_string_integer_append_two_digits (new_shifted_number, num_packed_byte);
                }
                num_packed_byte = temp_num->packed_number_block[i];
                if (temp_num->highest_nibble_position == hi)
                {
                  new_shifted_number = packed_string_integer_append_two_digits (new_shifted_number, num_packed_byte);
                }
                else
                {
                  if (temp_num->highest_nibble_position == lo)
                  {
                    num_nibble_low = num_packed_byte & 0x0f;
                    new_shifted_number = packed_string_integer_append_one_digit (new_shifted_number, num_nibble_low);
                  }
                  else
                  {
                    printf ("Internal error in packed_string_integer_shift_digits_left(): temp_num->highest_nibble_position is undefined. Exiting now.\n");
                    exit (EXIT_FAILURE);
                  }
                }
              }
              temp_num = temp_num->next_number_block;
            }
          }
        } 
      }
    } 
  }
  return new_shifted_number;
}




// **************************************************************************************************************************************************
// * packed_string_integer_factorial                                                                                                                *
// *                                                                                                                                                *
// * This subroutine calculates the factorial of a packed, string-based integer. For example, 10 factorial = 10 * 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1 *
// *                                                                                                                                                *
// * Input: a non-negative packed string-based integer                                                                                              *
// * Output: Upon success, the factorial result of the input number. On failure, NULL is returned.                                                  *
// **************************************************************************************************************************************************
psint * packed_string_integer_factorial (psint *number)
{
  psint *constant_zero, *constant_one, *counter, *factorial, *temp_factorial, *temp_counter;
  int counter_result, number_result;

  constant_zero  = NULL;
  constant_one   = NULL;
  counter        = NULL;
  factorial      = NULL;
  temp_factorial = NULL;
  temp_counter   = NULL;
  if (number != NULL)
  {
    if (number->left_of_decimal != NULL)
    {
      if (number->sign == positive)
      {
        constant_zero = packed_string_integer_initialize_to_zero (constant_zero);
        constant_one  = packed_string_integer_set_value (constant_one, "1");
        number_result = packed_string_integer_determine_absolute_value_larger_of_two_integers (number, constant_zero);
        if (number_result == 1)
        {
          counter        = packed_string_integer_copy_number (counter, number);
          factorial      = packed_string_integer_copy_number (factorial, number);
          counter_result = packed_string_integer_determine_absolute_value_number_greater_than_one (counter);
          while (counter_result == 1)
          {
            temp_counter   = packed_string_integer_subtract (temp_counter, counter, constant_one);
            counter        = packed_string_integer_component_release_memory (counter);
            counter        = packed_string_integer_copy_number (counter, temp_counter);
            temp_counter   = packed_string_integer_release_memory (temp_counter);
            temp_factorial = packed_string_integer_multiply_traditional (temp_factorial, factorial, counter);
            factorial      = packed_string_integer_component_release_memory (factorial);
            factorial      = packed_string_integer_copy_number (factorial, temp_factorial);
            temp_factorial = packed_string_integer_release_memory (temp_factorial); 
            counter_result = packed_string_integer_determine_absolute_value_number_greater_than_one (counter);
          }
          counter = packed_string_integer_release_memory (counter);
        } // if (number_result == 1)
        else
        {
          if (number_result == 0)
          {
            factorial = packed_string_integer_set_value (factorial, "1");
          }
        }
        constant_zero = packed_string_integer_release_memory (constant_zero);
        constant_one  = packed_string_integer_release_memory (constant_one);
      }
    }
    else
    {
      if (number->sign == zero)
      {
        factorial = packed_string_integer_set_value (factorial, "1");
      }
    }
  }
  return factorial;
}




// *********************************************************************************
// * packed_string_integer_factorial_v2                                            * 
// *                                                                               *
// * This subroutine calculates the factorial of a binary 64-bit unsigned integer. *
// * For example, 10 factorial = 10 * 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1            * 
// *                                                                               *
// * However, when this subroutine computes subsets of the final factorial. This   *
// * technique generates two large integers multiplied together rather than one    *
// * longer (digit-length) integer times a significantly shorter (digit-length)    *
// * integer. With two long integers multiplied together, one can take advantage   *
// * of the Toom-3 algorithm for multiplication of two long-length integers.       *
// *                                                                               *
// * Input: a packed string integer number structure.                              *
// *                                                                               *
// * Output: Upon success, the factorial result of the input number.               *
//           On failure, NULL is returned.                                         *
// *********************************************************************************
psint * packed_string_integer_factorial_v2 (psint *number)
{
  psint_list_node *psint_list, *psint2_list, *psint_element;
  psint *constant_zero, *constant_one, *counter, *factorial, *partial_factorial, *num1, *num2, *temp_factorial, *temp_counter;
  int counter_result, number_result;
  const unsigned long long int THRESHOLD = 40000; // last tested 40,000
  unsigned long long int partial_factorial_digit_count, num_partial_factorials_to_be_processed;

  psint_list    = NULL;
  psint2_list   = NULL;
  constant_zero = NULL;
  constant_one  = NULL;
  counter       = NULL;
  factorial     = NULL;
  num1          = NULL;
  num2          = NULL;
  partial_factorial = NULL;
  temp_factorial    = NULL;
  temp_counter      = NULL;
  if (number != NULL)
  {
    if (number->left_of_decimal != NULL)
    {
      if (number->sign == positive)
      {
        constant_zero = packed_string_integer_initialize_to_zero (constant_zero);
        constant_one  = packed_string_integer_set_value (constant_one, "1");
        number_result = packed_string_integer_determine_absolute_value_larger_of_two_integers (number, constant_zero);
        if (number_result == 1)
        {
          counter = packed_string_integer_copy_number (counter, number);
          partial_factorial = packed_string_integer_copy_number (partial_factorial, number);
          partial_factorial_digit_count = count_num_digits_in_packed_string_integer (partial_factorial);
          counter_result = packed_string_integer_determine_absolute_value_number_greater_than_one (counter);
          while (counter_result == 1)
          {
            while ((counter_result == 1) && (partial_factorial_digit_count < THRESHOLD))
            {
              temp_counter      = packed_string_integer_subtract (temp_counter, counter, constant_one);
              counter           = packed_string_integer_component_release_memory (counter);
              counter           = packed_string_integer_copy_number (counter, temp_counter);
              temp_counter      = packed_string_integer_release_memory (temp_counter);
              temp_factorial    = packed_string_integer_multiply_traditional (temp_factorial, partial_factorial, counter);
              partial_factorial = packed_string_integer_component_release_memory (partial_factorial);
              partial_factorial = packed_string_integer_copy_number (partial_factorial, temp_factorial);
              temp_factorial    = packed_string_integer_release_memory (temp_factorial); 
              counter_result    = packed_string_integer_determine_absolute_value_number_greater_than_one (counter);
              partial_factorial_digit_count = count_num_digits_in_packed_string_integer (partial_factorial);
            }
            //printf ("counter = ");
            //packed_string_integer_display (counter, 0);
            //printf ("\n");
            //printf ("partial_factorial = ");
            //packed_string_integer_display (partial_factorial, 0);
            //printf ("\n");
            psint_list = add_psint_element_to_list (psint_list, partial_factorial); 
            partial_factorial = packed_string_integer_component_release_memory (partial_factorial); 
            partial_factorial = packed_string_integer_set_value (partial_factorial, "1");
            partial_factorial_digit_count = 1;
          }
          partial_factorial = packed_string_integer_component_release_memory (partial_factorial);
// ***************************************************************************
// * Compute partial factorials on two partial factorials in the psint list. *      
// ***************************************************************************
          while ((psint_list != NULL) || (psint2_list != NULL))
          {
            psint_element = psint_list;
            while (psint_element != NULL)
            {
              num1 = psint_element->element;
              psint_element = psint_element->next_element;
              if (psint_element != NULL)
              {
                num2 = psint_element->element;
                partial_factorial = _packed_string_integer_multiply_with_toom3 (partial_factorial, num1, num2);
                //partial_factorial = packed_string_integer_multiply_traditional (partial_factorial, num1, num2);
                if (partial_factorial == NULL)
                {
                  printf ("Toom3 returned null for the following numbers:\n");
                  printf ("num1 = ");
                  packed_string_integer_display (num1, 0);
                  printf ("\n");
                  printf ("num2 = ");
                  packed_string_integer_display (num2, 0);
                  printf ("\n");
                  exit (EXIT_FAILURE);
                }
                //printf ("partial_factorial = ");
                //packed_string_integer_display (partial_factorial, 0);
                //printf ("\n");
                psint2_list = add_psint_element_to_list (psint2_list, partial_factorial);
                partial_factorial = packed_string_integer_component_release_memory (partial_factorial); 
                psint_element = psint_element->next_element;
              }
              else
              {
                psint2_list = add_psint_element_to_list (psint2_list, num1);
              }
            }
// *********************************************************************
// * Release memory from the psint list since all of those partial     *
// * factorials have now been multiplied together into larger numbers. *
// *********************************************************************
            while (psint_list != NULL)
            {
              psint_element = psint_list;
              psint_list = psint_list->next_element;
              partial_factorial = psint_element->element;
              partial_factorial = packed_string_integer_component_release_memory (partial_factorial);
              free (psint_element);
            }
// ********************************************************************************
// * If there is only one item in psint_list2, then the entire operation is done. *
// ********************************************************************************
            num_partial_factorials_to_be_processed = 0;
            psint_element = psint2_list;
            while ((psint_element != NULL) && (num_partial_factorials_to_be_processed < 2))
            {
              num_partial_factorials_to_be_processed++;
              psint_element = psint_element->next_element;
            }
            //printf ("num_partial_factorials_to_be_processed = %lld\n", num_partial_factorials_to_be_processed);
            if (num_partial_factorials_to_be_processed == 1)
            {
              if (psint_list != NULL)
              {
                factorial = psint_list->element;
                free (psint_list);
                psint_list = NULL;
              }
              else
              {
                if (psint2_list != NULL)
                {
                  factorial = psint2_list->element;
                  free (psint2_list);
                  psint2_list = NULL;
                }
              }
            }
            if (num_partial_factorials_to_be_processed >= 2)
            {
// ****************************************************************************
// * Compute partial factorials on two partial factorials in the psint2 list. *      
// ****************************************************************************
              psint_element = psint2_list;
              while (psint_element != NULL)
              {
                num1 = psint_element->element;
                psint_element = psint_element->next_element;
                if (psint_element != NULL)
                {
                  num2 = psint_element->element;
                  partial_factorial = _packed_string_integer_multiply_with_toom3 (partial_factorial, num1, num2);
                  //partial_factorial = packed_string_integer_multiply_traditional (partial_factorial, num1, num2);
                  if (partial_factorial == NULL)
                  {
                    printf ("Toom3 returned null for the following numbers:\n");
                    printf ("num1 = ");
                    packed_string_integer_display (num1, 0);
                    printf ("\n");
                    printf ("num2 = ");
                    packed_string_integer_display (num2, 0);
                    printf ("\n");
                    exit (EXIT_FAILURE);
                  }
                  //printf ("partial_factorial = ");
                  //packed_string_integer_display (partial_factorial, 0);
                  //printf ("\n");
                  psint_list = add_psint_element_to_list (psint_list, partial_factorial);
                  partial_factorial = packed_string_integer_component_release_memory (partial_factorial);
                  psint_element = psint_element->next_element;
                }
                else
                {
                  psint_list = add_psint_element_to_list (psint_list, num1);
                }
              }
// **********************************************************************
// * Release memory from the psint2 list since all of those partial     *
// * factorials have now been multiplied together into larger numbers.  *
// **********************************************************************
              while (psint2_list != NULL)
              {
                psint_element = psint2_list;
                psint2_list = psint2_list->next_element;
                partial_factorial = psint_element->element;
                partial_factorial = packed_string_integer_component_release_memory (partial_factorial);
                free (psint_element);
              }
            }
// *******************************************************************************
// * If there is only one item in psint_list, then the entire operation is done. *
// *******************************************************************************
            num_partial_factorials_to_be_processed = 0;
            psint_element = psint_list;
            while ((psint_element != NULL) && (num_partial_factorials_to_be_processed < 2))
            {
              num_partial_factorials_to_be_processed++;
              psint_element = psint_element->next_element;
            }
            if (num_partial_factorials_to_be_processed == 1)
            {
              if (psint_list != NULL)
              {
                factorial = psint_list->element;
                free (psint_list);
                psint_list = NULL;
              }
              else
              {
                if (psint2_list != NULL)
                {
                  factorial = psint2_list->element;
                  free (psint2_list);
                  psint2_list = NULL;
                }
              }
            }
            //printf ("num_partial_factorials_to_be_processed = %lld\n", num_partial_factorials_to_be_processed);
          }
          counter = packed_string_integer_component_release_memory (counter);
        } // if (number_result == 1)
        else
        {
          if (number_result == 0)
          {
            factorial = packed_string_integer_set_value (factorial, "1");
          }
        }
        constant_zero = packed_string_integer_release_memory (constant_zero);
        constant_one  = packed_string_integer_release_memory (constant_one);
      }
    }
    else
    {
      if (number->sign == zero)
      {
        factorial = packed_string_integer_set_value (factorial, "1");
      }
    }
  }
  return factorial;
}




unsigned char packed_string_integer_contains_only_two_and_five_as_factors (psint *number)
{
  psint_list_node *quotient_and_remainder;
  psint *new_number, *constant_0, *constant_1, *constant_2, *constant_5, *quotient, *remainder;
  psnc *temp_number_component;
  unsigned char found_a_zero_digit, found_a_nonzero_digit, is_divisible_by_two, is_divisible_by_five, packed_digit, nibble_low, nibble_high, digit;
  unsigned char only_twos_and_fives_are_factors, numbers_are_equal;
  long long int i;
  int greater_than_status;
  digit_stack_node *digit_stack;

  new_number      = NULL;
  constant_0      = NULL;
  constant_1      = NULL;
  constant_2      = NULL;
  constant_5      = NULL;
  digit_stack     = NULL;
  temp_number_component = NULL;
  quotient_and_remainder = NULL;
  quotient = NULL;
  remainder = NULL;
  only_twos_and_fives_are_factors = FALSE;
  numbers_are_equal = FALSE;
  constant_0 = packed_string_integer_initialize_to_zero (constant_0);
  constant_1 = packed_string_integer_set_value (constant_1, "1");
  constant_2 = packed_string_integer_set_value (constant_2, "2");
  constant_5 = packed_string_integer_set_value (constant_5, "5");
  if ((number != NULL) && (constant_1 != NULL) && (constant_2 != NULL) && (constant_5 != NULL))
  {
    if ((number->sign == positive) || (number->sign == negative))
    {
      if (number->left_of_decimal != NULL)
      {
// ****************************************************************
// * Remove all but one leading zero as least significant digits. *
// *                                                              *
// * Example:      123 (before) becomes   123 (after)             *
// * Example:  1230000 (before) becomes  1230 (after)             *
// * Example:    45670 (before) becomes 45670 (after)             *
// ****************************************************************
        temp_number_component = number->left_of_decimal->last_number_block;
        while (temp_number_component != NULL)
        {
          if ((temp_number_component->highest_digit_position >= 0) && (temp_number_component->highest_digit_position < MAX_PACKED_NUMBER_BLOCK_SIZE))
          {
            i = temp_number_component->highest_digit_position;
            packed_digit = temp_number_component->packed_number_block[i];
            if (temp_number_component->highest_nibble_position == lo)
            {
              nibble_low = (packed_digit & 0x0f) + '0';;
              digit_stack = push_digit_stack (digit_stack, nibble_low);
            }
            else
            {
              if (temp_number_component->highest_nibble_position == hi)
              {
                nibble_high = ((packed_digit & 0xf0) >> 4) + '0';
                nibble_low = (packed_digit & 0x0f) + '0';;
                digit_stack = push_digit_stack (digit_stack, nibble_high);
                digit_stack = push_digit_stack (digit_stack, nibble_low);
              }
              else
              {
                printf ("Error in number_contains_only_two_and_five_as_factors(): temp_number_component->highest_nibble_position is undefined. Exiting now.\n");
                exit (EXIT_FAILURE);
              }
            }
            for (i = temp_number_component->highest_digit_position - 1; i >= 0; i--)
            {
              packed_digit = temp_number_component->packed_number_block[i];
              nibble_high = ((packed_digit & 0xf0) >> 4) + '0';
              nibble_low = (packed_digit & 0x0f) + '0';
              digit_stack = push_digit_stack (digit_stack, nibble_high);
              digit_stack = push_digit_stack (digit_stack, nibble_low);
            }
          }
          else
          {
            printf ("Error in number_contains_only_two_and_five_as_factors(): temp_number_component->highest_digit_position is greater than MAX_PACKED_NUMBER_BLOCK_SIZE. Exiting now.\n");
            exit (EXIT_FAILURE);
          }
          temp_number_component = temp_number_component->previous_number_block;
        } 
// **********************************************************************************************
// * Now copy remaining digits to a new number without the leading zeros (except for one zero). *
// **********************************************************************************************
        found_a_zero_digit = FALSE;
        found_a_nonzero_digit = FALSE;
        while ((digit_stack != NULL) && (!found_a_nonzero_digit))
        {
          digit = top_digit_stack (digit_stack);
          if (digit > '0')
          {
            found_a_nonzero_digit = TRUE;
          }
          else
          {
            found_a_zero_digit = TRUE;
            digit_stack = pop_digit_stack (digit_stack);
          }
        }         
        if (found_a_zero_digit)
        {
          digit_stack = push_digit_stack (digit_stack, '0');
        }
        while (digit_stack != NULL)
        {
          digit = top_digit_stack (digit_stack);
          digit = digit - '0';
          new_number = packed_string_integer_append_one_digit (new_number, digit);
          digit_stack = pop_digit_stack (digit_stack);
        }
        if (new_number != NULL)
        {
          new_number = packed_string_integer_set_sign (new_number, number->sign);
          new_number = packed_string_integer_set_status_flag (new_number, NONE);
        }
      }
    }
  }
  if (new_number != NULL)
  {
    is_divisible_by_five = packed_string_integer_is_divisible_by_five (new_number);
    if (is_divisible_by_five)
    {
      do
      {
        quotient_and_remainder = packed_string_integer_divide_returning_quotient_and_remainder (new_number, constant_5);
        if (quotient_and_remainder != NULL)
        {
          if (quotient_and_remainder->next_element != NULL)
          {
            quotient = quotient_and_remainder->element;
            remainder = quotient_and_remainder->next_element->element;
            if ((quotient != NULL) && (remainder != NULL))
            {
              numbers_are_equal = packed_string_integer_equal (remainder, constant_0);
              if (numbers_are_equal == TRUE)
              {
                new_number = packed_string_integer_component_release_memory (new_number);
                new_number = packed_string_integer_copy_number (new_number, quotient);
              }
              quotient = packed_string_integer_component_release_memory (quotient);
              remainder = packed_string_integer_component_release_memory (remainder);
              free (quotient_and_remainder->next_element);
              free (quotient_and_remainder);
            }
          }                  
        }
      }
      while (numbers_are_equal == TRUE);
    }
    is_divisible_by_two = packed_string_integer_is_divisible_by_two (new_number);
    if (is_divisible_by_two)
    {
      do
      {
        quotient_and_remainder = packed_string_integer_divide_returning_quotient_and_remainder (new_number, constant_2);
        if (quotient_and_remainder != NULL)
        {
          if (quotient_and_remainder->next_element != NULL)
          {
            quotient = quotient_and_remainder->element;
            remainder = quotient_and_remainder->next_element->element;
            if ((quotient != NULL) && (remainder != NULL))
            {
              numbers_are_equal = packed_string_integer_equal (remainder, constant_0);
              if (numbers_are_equal)
              {
                new_number = packed_string_integer_component_release_memory (new_number);
                new_number = packed_string_integer_copy_number (new_number, quotient);
              }
              quotient = packed_string_integer_component_release_memory (quotient);
              remainder = packed_string_integer_component_release_memory (remainder);
              free (quotient_and_remainder->next_element);
              free (quotient_and_remainder);
            }
          }                  
        }
      }
      while (numbers_are_equal == 1);
    }
  }
  if (new_number != NULL)
  {
    greater_than_status = packed_string_integer_determine_absolute_value_larger_of_two_integers (new_number, constant_1);
    if (greater_than_status == 0)
    {
      only_twos_and_fives_are_factors = TRUE;
    }
    new_number = packed_string_integer_release_memory (new_number);
  }
  return only_twos_and_fives_are_factors;
}




// ************************************************************************************************************
// * convert_packed_string_integer_to_packed_string_float                                                     *
// *                                                                                                          *
// * This function converts a packed string integer data structure into a packed string float data structure. *
// *                                                                                                          *
// * Input:  The string-based integer number to be converted to float.                                        *
// * Output: NULL on failure; pointer to a string-based float on success.                                     *
// ************************************************************************************************************
psflt * convert_packed_string_integer_to_packed_string_float (psflt *converted_number, psint *number)
{
  psnc *new_number_block, *number_copy_previous, *temp_num;
  int state;
  unsigned char nibble_lo, packed_byte;
  long long int i;

// *************************************************************************
// * Release any previously used memory otherwise we'd have a memory leak. *
// *************************************************************************
  if (converted_number != NULL)
  {
    converted_number = packed_string_float_component_release_memory (converted_number);
  }
  if (number != NULL)
  {
    if (converted_number == NULL)
    {
      converted_number = (psflt *) malloc(sizeof(psflt));
    }
    if (converted_number != NULL)
    {
      converted_number->sign             = number->sign;
      converted_number->status_flag      = NONE;
      converted_number->left_of_decimal  = NULL;
      converted_number->right_of_decimal = NULL;
      converted_number->scale            = number->scale;
      if (number->left_of_decimal != NULL)
      {
        new_number_block     = NULL;
        number_copy_previous = NULL;
        nibble_lo            = 0;
        packed_byte          = 0;
        state                = 0;
        temp_num             = number->left_of_decimal;
        while (temp_num != NULL)
        {
          new_number_block = (psnc *) malloc(sizeof(psnc));
          if (new_number_block != NULL)
          {
            new_number_block->highest_digit_position  = temp_num->highest_digit_position;
            new_number_block->highest_nibble_position = temp_num->highest_nibble_position;
            new_number_block->first_number_block      = NULL;
            new_number_block->last_number_block       = NULL;
            new_number_block->previous_number_block   = NULL;
            new_number_block->next_number_block       = NULL;
            for (i = temp_num->highest_digit_position + 1; i < MAX_PACKED_NUMBER_BLOCK_SIZE; i++)
            {
              new_number_block->packed_number_block[i] = 0;
            }
            for (i = 0; i < temp_num->highest_digit_position; i++)
            {
              new_number_block->packed_number_block[i] = temp_num->packed_number_block[i];
            }
            if (temp_num->highest_nibble_position == hi)
            {
              new_number_block->packed_number_block[i] = temp_num->packed_number_block[i];
            }
            else
            {
              if (temp_num->highest_nibble_position == lo)
              {
                packed_byte = temp_num->packed_number_block[i];
                nibble_lo = packed_byte & 0x0f;
                new_number_block->packed_number_block[i] = nibble_lo;
              }
            }
            switch (state)
            {
              case 0:
                converted_number->left_of_decimal = new_number_block;
                converted_number->left_of_decimal->first_number_block = new_number_block;
                number_copy_previous = NULL;
                state  = 10;
              break;
              case 10:
                if (number_copy_previous != NULL)
                {
                  number_copy_previous->next_number_block = new_number_block;
                }
                new_number_block->first_number_block    = converted_number->left_of_decimal;
                new_number_block->previous_number_block = number_copy_previous; 
              break;
              default:
              break;
            }
            number_copy_previous = new_number_block;
          }
          temp_num = temp_num->next_number_block;
        }
        if (new_number_block != NULL)
        {
          temp_num = converted_number->left_of_decimal;
          while (temp_num != NULL)
          {
            temp_num->last_number_block = new_number_block;
            temp_num = temp_num->next_number_block;
          }
        }
      }
    }
  }
  return converted_number;
} 




unsigned char * convert_packed_string_integer_to_boolean (psint *num1)
{
  psint *constant_one;
  unsigned char *converted_bool_value;
  int greater_number;

  constant_one = NULL;
  converted_bool_value = NULL;
  constant_one = packed_string_integer_set_value (constant_one, "1");
  if ((num1 != NULL) && (constant_one != NULL))
  {
    greater_number = packed_string_integer_determine_absolute_value_larger_of_two_integers (num1, constant_one);
    switch (greater_number)
    {
      case 1: // |num1| > |num2|.
        converted_bool_value = (unsigned char *) malloc(sizeof(unsigned char));
        if (converted_bool_value != NULL)
        {
          *converted_bool_value = TRUE;
        }
      break;
      case 0: // |num1| == |num2|
        converted_bool_value = (unsigned char *) malloc(sizeof(unsigned char));
        if (converted_bool_value != NULL)
        {
          *converted_bool_value = TRUE;
        }
      break;
      case -1: // num1 < num2
        converted_bool_value = (unsigned char *) malloc(sizeof(unsigned char));
        if (converted_bool_value != NULL)
        {
          if (num1->sign == zero) 
          {
            *converted_bool_value = FALSE;
          }
          else
          {
            *converted_bool_value = TRUE;
          }
        }
      break;
      case -2:
      break;
      default:
      break;
    }
    constant_one = packed_string_integer_release_memory (constant_one);
  }
  return converted_bool_value;
}




psint * convert_boolean_to_packed_string_integer (unsigned char *boolean_value)
{
  psint *converted_integer_value;

  converted_integer_value = NULL;
  if (boolean_value != NULL)
  {
    if (*boolean_value == FALSE)
    {
      converted_integer_value = packed_string_integer_set_value (converted_integer_value, "0");
    }
    else
    {
      if (*boolean_value == TRUE)
      {
        converted_integer_value = packed_string_integer_set_value (converted_integer_value, "1");
      }
    }
  }
  return converted_integer_value;
}
