/***********************************************************************************
 * 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 <stdio.h>
#include "include/libchaga-main.h"
#include "include/libchaga-constants.h"
#include "include/libchaga-general_functions.h"

void main (void)
{
  unsigned long long int num_digits_of_precision_right_of_decimal, current_fibonacci_term, number_of_fibonacci_terms;
  int i, state;
// ***************************************************************************************************************
// * psint stands for Packed String Integer. It stored two digits per byte in Binary Coded Decimal (BCD) format. *
// ***************************************************************************************************************
  psint *result, *test1_num1, *test2_num1, *test2_num2, *test3_num1, *test3_num2, *test3_num3, *test3_num4, *test3_num5;
  psint *test4_num1, *test4_num2, *test5_num1, *test5_num2, *test6_num1, *test6_num2, *test15_num1, *test15_num2;
  psint *test20_num1, *test20_num2, *temp_resultA, *temp_resultB, *temp_resultC, *temp_resultD, *temp_resultE;
// *****************************************************************************************************************************************
// * psflt stands for Packed String FLoaT. Like psint this data structure stores two digits per byte in Binary Coded Decimal (BCD) format. * 
// *****************************************************************************************************************************************
  psflt *result_float, *test7_num1, *test8_num1, *test9_num1, *test9_num2, *test10_num1, *test10_num2, *test11_num1, *test11_num2;
  psflt *test12_num1, *test12_num2, *test13_num1, *test13_num2, *test14_num1, *test14_num2, *test16_num1, *test16_num2;
  psflt *test17_num1, *test17_num2, *test18_num1, *test18_num2, *test19_num1, *test19_num2;

// ******************************************************************************
// * All Chaga string-based datatypes must be initialized to NULL before usage. *
// ******************************************************************************
  result       = NULL;
  result_float = NULL;
  temp_resultA = NULL;
  temp_resultB = NULL;
  temp_resultC = NULL;
  temp_resultD = NULL;
  temp_resultE = NULL;
  test1_num1   = NULL;
  test2_num1   = NULL;
  test2_num2   = NULL;
  test3_num1   = NULL;
  test3_num2   = NULL;
  test3_num3   = NULL;
  test3_num4   = NULL;
  test3_num5   = NULL;
  test4_num1   = NULL;
  test4_num2   = NULL;
  test5_num1   = NULL;
  test5_num2   = NULL;
  test6_num1   = NULL;
  test6_num2   = NULL;
  test7_num1   = NULL;
  test8_num1   = NULL;
  test9_num1   = NULL;
  test10_num1  = NULL;
  test10_num2  = NULL;
  test11_num1  = NULL;
  test11_num2  = NULL;
  test12_num1  = NULL;
  test12_num2  = NULL;
  test13_num1  = NULL;
  test13_num2  = NULL;
  test14_num1  = NULL;
  test14_num2  = NULL;
  test15_num1  = NULL;
  test15_num2  = NULL;
  test16_num1  = NULL;
  test16_num2  = NULL;
  test17_num1  = NULL;
  test17_num2  = NULL;
  test18_num1  = NULL;
  test18_num2  = NULL;
  test19_num1  = NULL;
  test19_num2  = NULL;
  test20_num1  = NULL;
  test20_num2  = NULL;


  printf ("\n\n\n");  
  printf ("**********\n");
  printf ("* TEST 1 *\n");
  printf ("**********\n");
// ***************************************************************************
// * A quick way to initialize a number is to call string integer set value. *
// ***************************************************************************
  test1_num1 = packed_string_integer_set_value (test1_num1, "1000");

// ************************************
// * Calculate one-thousand factorial *
// ************************************
  packed_string_integer_display (test1_num1, 0);
  printf ("! = ");

// ****************************
// * Calculate the factorial. *
// ****************************
  result = packed_string_integer_factorial (test1_num1);

// *******************************************
// * Print the result (factorial) on screen. *
// *******************************************
  packed_string_integer_display (result, 0); // The "0" is a Boolean value. It determines if we should display a "+" on positive integers. FALSE means don't display a plus for positive integers.
  printf ("\n\n\n");

// **************************************************
// * Release memory utilized by the string integer. *
// **************************************************
  test1_num1  = packed_string_integer_release_memory (test1_num1);
  result = packed_string_integer_release_memory (result);


  printf ("**********\n");
  printf ("* TEST 2 *\n");
  printf ("**********\n");
// *****************************************************************************************************
// * Calculate the product of +1234567890123456789012345678901234567890 * -987654321987654321987654321 *
// *****************************************************************************************************
  test2_num1 = packed_string_integer_set_value (test2_num1, "+1234567890123456789012345678901234567890");
  test2_num2 = packed_string_integer_set_value (test2_num2, "-987654321987654321987654321");
  packed_string_integer_display (test2_num1, 0);
  printf (" * ");
  packed_string_integer_display (test2_num2, 0);
  printf (" = ");
  result = packed_string_integer_multiply (result, test2_num1, test2_num2);
  packed_string_integer_display (result, 0);
  printf ("\n\n\n");
  test2_num1 = packed_string_integer_release_memory (test2_num1);
  test2_num2 = packed_string_integer_release_memory (test2_num2);
  result     = packed_string_integer_release_memory (result);


  printf ("**********\n");
  printf ("* TEST 3 *\n");
  printf ("**********\n");
// **************************************************************************************************************************
// * Calculate the sum of 99999999999999999 + 88888888888888888 + 77777777777777777 + 66666666666666666 + 55555555555555555 *
// **************************************************************************************************************************
  test3_num1 = packed_string_integer_set_value (test3_num1, "99999999999999999");
  test3_num2 = packed_string_integer_set_value (test3_num2, "88888888888888888");
  test3_num3 = packed_string_integer_set_value (test3_num3, "77777777777777777");
  test3_num4 = packed_string_integer_set_value (test3_num4, "66666666666666666");
  test3_num5 = packed_string_integer_set_value (test3_num5, "55555555555555555");
  packed_string_integer_display (test3_num1, 0);
  printf (" + ");
  packed_string_integer_display (test3_num2, 0);
  printf (" + ");
  packed_string_integer_display (test3_num3, 0);
  printf (" + ");
  packed_string_integer_display (test3_num4, 0);
  printf (" + ");
  packed_string_integer_display (test3_num5, 0);
  printf (" = ");
  temp_resultA = packed_string_integer_add (temp_resultA, test3_num1,   test3_num2);
  temp_resultB = packed_string_integer_add (temp_resultB, temp_resultA, test3_num3);
  temp_resultC = packed_string_integer_add (temp_resultC, temp_resultB, test3_num4);
  result       = packed_string_integer_add (result,       temp_resultC, test3_num5);
  packed_string_integer_display (result, 0);
  printf ("\n\n\n");
  test3_num1   = packed_string_integer_release_memory (test3_num1);
  test3_num2   = packed_string_integer_release_memory (test3_num2);
  test3_num3   = packed_string_integer_release_memory (test3_num3);
  test3_num4   = packed_string_integer_release_memory (test3_num4);
  test3_num5   = packed_string_integer_release_memory (test3_num5);
  temp_resultA = packed_string_integer_release_memory (temp_resultA);
  temp_resultB = packed_string_integer_release_memory (temp_resultB);
  temp_resultC = packed_string_integer_release_memory (temp_resultC);
  result       = packed_string_integer_release_memory (result);


  printf ("**********\n");
  printf ("* TEST 4 *\n");
  printf ("**********\n");
// **********************************************************************************************************************************************************************************************
// * Calculate the sum of 11111010101111111000000111100000000000000000000111111000000000000000100000000000000000 - 9999999999999999999999999999999999999999999999999999999999999999999999999999 *
// **********************************************************************************************************************************************************************************************
  test4_num1 = packed_string_integer_set_value (test4_num1, "11111010101111111000000111100000000000000000000111111000000000000000100000000000000000");
  test4_num2 = packed_string_integer_set_value (test4_num2, "9999999999999999999999999999999999999999999999999999999999999999999999999999");
  packed_string_integer_display (test4_num1, 0);
  printf (" - ");
  packed_string_integer_display (test4_num2, 0);
  printf (" = ");
  result = packed_string_integer_subtract (result, test4_num1, test4_num2);
  packed_string_integer_display (result, 0);
  printf ("\n\n\n");
  test4_num1 = packed_string_integer_release_memory (test4_num1);
  test4_num2 = packed_string_integer_release_memory (test4_num2);
  result     = packed_string_integer_release_memory (result);


  printf ("**********\n");
  printf ("* TEST 5 *\n");
  printf ("**********\n");
// *******************************************************************************************************************************
// * Calculate the sum of 123456789012345678901234567890123456789012345678901234567890 / 987654321987654321098765432109876543210 *
// *******************************************************************************************************************************
  test5_num1 = packed_string_integer_set_value (test5_num1, "123456789012345678901234567890123456789012345678901234567890");
  test5_num2 = packed_string_integer_set_value (test5_num2, "987654321987654321098765432109876543210");
  packed_string_integer_display (test5_num1, 0);
  printf (" / ");
  packed_string_integer_display (test5_num2, 0);
  printf (" = ");
  result = packed_string_integer_divide (result, test5_num1, test5_num2);
  packed_string_integer_display (result, 0);
  printf ("\n\n\n");
  test5_num1 = packed_string_integer_release_memory (test5_num1);
  test5_num2 = packed_string_integer_release_memory (test5_num2);
  result     = packed_string_integer_release_memory (result);


  printf ("**********\n");
  printf ("* TEST 6 *\n");
  printf ("**********\n");
// *******************************************************************************************************************************
// * Calculate the sum of 123456789012345678901234567890123456789012345678901234567890 % 987654321987654321098765432109876543210 *
// *******************************************************************************************************************************
  test6_num1 = packed_string_integer_set_value (test6_num1, "123456789012345678901234567890123456789012345678901234567890");
  test6_num2 = packed_string_integer_set_value (test6_num2, "987654321987654321098765432109876543210");
  packed_string_integer_display (test6_num1, 0);
  printf (" %% ");
  packed_string_integer_display (test6_num2, 0);
  printf (" = ");
  result = packed_string_integer_modulo (result, test6_num1, test6_num2);
  packed_string_integer_display (result, 0);
  printf ("\n\n\n");
  test6_num1 = packed_string_integer_release_memory (test6_num1);
  test6_num2 = packed_string_integer_release_memory (test6_num2);
  result     = packed_string_integer_release_memory (result);


  printf ("******************************************************\n");
  printf ("* TEST 7 (cube root of 2000 using bisection method). *\n");
  printf ("******************************************************\n");
// ***********************************************************
// * Calculate the cube root of 2000 using bisection method. *
// ***********************************************************
  test7_num1 = packed_string_float_set_value (test7_num1, "2000");
  printf ("The cube root of ");
  packed_string_float_display (test7_num1, 0);
  printf (" = ");
  result_float = packed_string_float_nth_root_with_bisection_method (result_float, test7_num1, 3);
  packed_string_float_display (result_float, 0);
  printf ("\n\n\n");
  test7_num1   = packed_string_float_release_memory (test7_num1);
  result_float = packed_string_float_release_memory (result_float);

 
  printf ("****************************************************************************************\n");
  printf ("* TEST 8 (cube root of 2000 using Newton-Raphson method seeded with bisection method). *\n");
  printf ("****************************************************************************************\n");
// ****************************************************************************************
// * Calculate the cube root of 2000 Newton-Raphson method seeded with bisection method). *
// ****************************************************************************************
  test8_num1 = packed_string_float_set_value (test8_num1, "2000");
  printf ("The cube root of ");
  packed_string_float_display (test8_num1, 0);
  printf (" = ");
  result_float = packed_string_float_nth_root_with_newton_raphson_method (result_float, test8_num1, 3);
  packed_string_float_display (result_float, 0);
  printf ("\n\n\n");
  test8_num1 = packed_string_float_release_memory (test8_num1);


  printf ("*****************************************************\n");
  printf ("* TEST 9 (test result 8 raised to the third power). *\n");
  printf ("*****************************************************\n");
  test9_num1   = packed_string_float_copy_number (test9_num1, result_float);
  result_float = packed_string_float_release_memory (result_float);
  packed_string_float_display (test9_num1, 0);
  printf (" raised to the third power = ");
  result_float = packed_string_float_power (result_float, test9_num1, 3);
  packed_string_float_display (result_float, 0);
  printf ("\n\n\n");
  test9_num1   = packed_string_float_release_memory (test9_num1);
  result_float = packed_string_float_release_memory (result_float);


  printf ("***********\n");
  printf ("* TEST 10 *\n");
  printf ("***********\n");
// ***********************************************************************
// * Calculate the sum of 1234567890.0987654321 + 123123123123.456456456 *
// ***********************************************************************
  test10_num1 = packed_string_float_set_value (test10_num1, "1234567890.0987654321");
  test10_num2 = packed_string_float_set_value (test10_num2, "123123123123.456456456456");
  packed_string_float_display (test10_num1, 0);
  printf (" + ");
  packed_string_float_display (test10_num2, 0);
  printf (" = ");
  result_float = packed_string_float_add (result_float, test10_num1, test10_num2);
  packed_string_float_display (result_float, 0);
  printf ("\n\n\n");
  test9_num1   = packed_string_float_release_memory (test10_num1);
  test9_num2   = packed_string_float_release_memory (test10_num2);
  result_float = packed_string_float_release_memory (result_float);


  printf ("***********\n");
  printf ("* TEST 11 *\n");
  printf ("***********\n");
// ***********************************************************************************************************************************************************************
// * Calculate the difference of 1000000010000000.000000000100000000001 - 090909090909090909090909090909.090909090909090090909090909090909090909090909090909090909090909 *
// ***********************************************************************************************************************************************************************
  test11_num1 = packed_string_float_set_value (test11_num1, "1000000010000000.000000000100000000001");
  test11_num2 = packed_string_float_set_value (test11_num2, "090909090909090909090909090909.090909090909090090909090909090909090909090909090909090909090909");
  packed_string_float_display (test11_num1, 0);
  printf (" - ");
  packed_string_float_display (test11_num2, 0);
  printf (" = ");
  result_float = packed_string_float_subtract (result_float, test11_num1, test11_num2);
  packed_string_float_display (result_float, 0);
  printf ("\n\n\n");
  test11_num1  = packed_string_float_release_memory (test11_num1);
  test11_num2  = packed_string_float_release_memory (test11_num2);
  result_float = packed_string_float_release_memory (result_float);


  printf ("***********\n");
  printf ("* TEST 12 *\n");
  printf ("***********\n");
// *****************************************************************************************
// * Calculate the product of 0.00000000000000000123000123000012300001230009 * 87654321.09 *
// *****************************************************************************************
  test12_num1 = packed_string_float_set_value (test12_num1, "0.00000000000000000123000123000012300001230009");
  test12_num2 = packed_string_float_set_value (test12_num2, "87654321.09");
  packed_string_float_display (test12_num1, 0);
  printf (" * ");
  packed_string_float_display (test12_num2, 0);
  printf (" = ");
  result_float = packed_string_float_multiply (result_float, test12_num1, test12_num2);
  packed_string_float_display (result_float, 0);
  printf ("\n\n\n");
  test12_num1  = packed_string_float_release_memory (test12_num1);
  test12_num2  = packed_string_float_release_memory (test12_num2);
  result_float = packed_string_float_release_memory (result_float);
  

  printf ("***********\n");
  printf ("* TEST 13 *\n");
  printf ("***********\n");
// *****************************************************
// * Calculate the division of 123456.10 / 654321.1234 *
// *****************************************************
  num_digits_of_precision_right_of_decimal = 10;
  test13_num1 = packed_string_float_set_value (test13_num1, "3");
  test13_num2 = packed_string_float_set_value (test13_num2, "8");
  packed_string_float_display (test13_num1, 0);
  printf (" / ");
  packed_string_float_display (test13_num2, 0);
  printf (" = ");
  result_float = packed_string_float_divide (result_float, test13_num1, test13_num2, num_digits_of_precision_right_of_decimal);
  packed_string_float_display (result_float, 0);
  printf ("\n\n\n");
  test13_num1  = packed_string_float_release_memory (test13_num1);
  test13_num2  = packed_string_float_release_memory (test13_num2);
  result_float = packed_string_float_release_memory (result_float);


  printf ("*********************************************\n");
  printf ("* TEST 14: floating-point division by zero. *\n");
  printf ("*********************************************\n");
  num_digits_of_precision_right_of_decimal = 10;
  test14_num1 = packed_string_float_set_value (test14_num1, "1");
  test14_num2 = packed_string_float_set_value (test14_num2, "0");
  packed_string_float_display (test14_num1, 0);
  printf (" / ");
  packed_string_float_display (test14_num2, 0);
  printf (" = ");
  result_float = packed_string_float_divide (result_float, test14_num1, test14_num2, num_digits_of_precision_right_of_decimal);
  packed_string_float_display (result_float, 0);
  if (result_float != NULL)
  {
    if ((result_float->status_flag & 0x8000) == INTERNAL_ERROR)
    {
      printf (" (INTERNAL ERROR)");
    }
    if ((result_float->status_flag & 0x4000) == DIVIDE_BY_ZERO)
    {
      printf (" (DIVIDE BY ZERO)");
    }
    if ((result_float->status_flag & 0x2000) == REPEATING_NONTERMINATING)
    {
      printf (" (REPEATING NONTERMINATING)");
    }
    if ((result_float->status_flag & 0x1000) == IMAGINARY)
    {
      printf (" (IMAGINARY)");
    }
  }
  printf ("\n\n\n");
  test14_num1  = packed_string_float_release_memory (test14_num1);
  test14_num2  = packed_string_float_release_memory (test14_num2);
  result_float = packed_string_float_release_memory (result_float);


  printf ("**************************************\n");
  printf ("* TEST 15: integer division by zero. *\n");
  printf ("**************************************\n");
  test15_num1 = packed_string_integer_set_value (test15_num1, "1");
  test15_num2 = packed_string_integer_set_value (test15_num2, "0");
  packed_string_integer_display (test15_num1, 0);
  printf (" / ");
  packed_string_integer_display (test15_num2, 0);
  printf (" = ");
  result = packed_string_integer_divide (result, test15_num1, test15_num2);
  packed_string_integer_display (result, 0);
  if (result != NULL)
  {
    if ((result->status_flag & 0x8000) == INTERNAL_ERROR)
    {
      printf (" (INTERNAL ERROR)");
    }
    if ((result->status_flag & 0x4000) == DIVIDE_BY_ZERO)
    {
      printf (" (DIVIDE BY ZERO)");
    }
    if ((result->status_flag & 0x2000) == REPEATING_NONTERMINATING)
    {
      printf (" (REPEATING NONTERMINATING)");
    }
    if ((result->status_flag & 0x1000) == IMAGINARY)
    {
      printf (" (IMAGINARY)");
    }
  }
  printf ("\n\n\n");
  test15_num1 = packed_string_integer_release_memory (test15_num1);
  test15_num2 = packed_string_integer_release_memory (test15_num2);
  result = packed_string_integer_release_memory (result);


  printf ("*************************************************************************************************************************************\n");
  printf ("* TEST 16: floating-point division with a repeating, non-terminating remainder (with 100 digits of precision right of the decimal). *\n");
  printf ("*************************************************************************************************************************************\n");
  num_digits_of_precision_right_of_decimal = 100;
  test16_num1 = packed_string_float_set_value (test16_num1, "1");
  test16_num2 = packed_string_float_set_value (test16_num2, "7");
  packed_string_float_display (test16_num1, 0);
  printf (" / ");
  packed_string_float_display (test16_num2, 0);
  printf (" = ");
  result_float = packed_string_float_divide (result_float, test16_num1, test16_num2, num_digits_of_precision_right_of_decimal);
  packed_string_float_display (result_float, 0);
  if (result_float != NULL)
  {
    if ((result_float->status_flag & 0x8000) == INTERNAL_ERROR)
    {
      printf (" (INTERNAL ERROR)");
    }
    if ((result_float->status_flag & 0x4000) == DIVIDE_BY_ZERO)
    {
      printf (" (DIVIDE BY ZERO)");
    }
    if ((result_float->status_flag & 0x2000) == REPEATING_NONTERMINATING)
    {
      printf (" (REPEATING NONTERMINATING)");
    }
    if ((result_float->status_flag & 0x1000) == IMAGINARY)
    {
      printf (" (IMAGINARY)");
    }
  }
  printf ("\n\n\n");
  test16_num1  = packed_string_float_release_memory (test16_num1);
  test16_num2  = packed_string_float_release_memory (test16_num2);
  result_float = packed_string_float_release_memory (result_float);


  printf ("************************************************************************************************************************************\n");
  printf ("* TEST 17: floating-point division with a repeating, non-terminating remainder (with 70 digits of precision right of the decimal). *\n");
  printf ("************************************************************************************************************************************\n");
  num_digits_of_precision_right_of_decimal = 70;
  test17_num1 = packed_string_float_set_value (test17_num1, "1");
  test17_num2 = packed_string_float_set_value (test17_num2, "103");
  packed_string_float_display (test17_num1, 0);
  printf (" / ");
  packed_string_float_display (test17_num2, 0);
  printf (" = ");
  result_float = packed_string_float_divide (result_float, test17_num1, test17_num2, num_digits_of_precision_right_of_decimal);
  packed_string_float_display (result_float, 0);
  if (result_float != NULL)
  {
    if ((result_float->status_flag & 0x8000) == INTERNAL_ERROR)
    {
      printf (" (INTERNAL ERROR)");
    }
    if ((result_float->status_flag & 0x4000) == DIVIDE_BY_ZERO)
    {
      printf (" (DIVIDE BY ZERO)");
    }
    if ((result_float->status_flag & 0x2000) == REPEATING_NONTERMINATING)
    {
      printf (" (REPEATING NONTERMINATING)");
    }
    if ((result_float->status_flag & 0x1000) == IMAGINARY)
    {
      printf (" (IMAGINARY)");
    }
  }
  printf ("\n\n\n");
  test17_num1  = packed_string_float_release_memory (test17_num1);
  test17_num2  = packed_string_float_release_memory (test17_num2);
  result_float = packed_string_float_release_memory (result_float);


  printf ("***********************************************************************************************************************************\n");
  printf ("* TEST 18: floating-point division with a repeating, non-terminating remainder (with 8 digits of precision right of the decimal). *\n");
  printf ("***********************************************************************************************************************************\n");
  num_digits_of_precision_right_of_decimal = 8;
  test18_num1 = packed_string_float_set_value (test18_num1, "1");
  test18_num2 = packed_string_float_set_value (test18_num2, "99");
  packed_string_float_display (test18_num1, 0);
  printf (" / ");
  packed_string_float_display (test18_num2, 0);
  printf (" = ");
  result_float = packed_string_float_divide (result_float, test18_num1, test18_num2, num_digits_of_precision_right_of_decimal);
  packed_string_float_display (result_float, 0);
  if (result_float != NULL)
  {
    if ((result_float->status_flag & 0x8000) == INTERNAL_ERROR)
    {
      printf (" (INTERNAL ERROR)");
    }
    if ((result_float->status_flag & 0x4000) == DIVIDE_BY_ZERO)
    {
      printf (" (DIVIDE BY ZERO)");
    }
    if ((result_float->status_flag & 0x2000) == REPEATING_NONTERMINATING)
    {
      printf (" (REPEATING NONTERMINATING)");
    }
    if ((result_float->status_flag & 0x1000) == IMAGINARY)
    {
      printf (" (IMAGINARY)");
    }
  }
  printf ("\n\n\n");
  test18_num1  = packed_string_float_release_memory (test18_num1);
  test18_num2  = packed_string_float_release_memory (test18_num2);
  result_float = packed_string_float_release_memory (result_float);


  printf ("**********************************************************************************************************************************\n");
  printf ("* TEST 19: floating-point division with a repeating, non-terminating remainder (with 1 digit of precision right of the decimal). *\n");
  printf ("**********************************************************************************************************************************\n");
  num_digits_of_precision_right_of_decimal = 1;
  test19_num1 = packed_string_float_set_value (test19_num1, "1");
  test19_num2 = packed_string_float_set_value (test19_num2, "3");
  packed_string_float_display (test19_num1, 0);
  printf (" / ");
  packed_string_float_display (test19_num2, 0);
  printf (" = ");
  result_float = packed_string_float_divide (result_float, test19_num1, test19_num2, num_digits_of_precision_right_of_decimal);
  packed_string_float_display (result_float, 0);
  if (result_float != NULL)
  {
    if ((result_float->status_flag & 0x8000) == INTERNAL_ERROR)
    {
      printf (" (INTERNAL ERROR)");
    }
    if ((result_float->status_flag & 0x4000) == DIVIDE_BY_ZERO)
    {
      printf (" (DIVIDE BY ZERO)");
    }
    if ((result_float->status_flag & 0x2000) == REPEATING_NONTERMINATING)
    {
      printf (" (REPEATING NONTERMINATING)");
    }
    if ((result_float->status_flag & 0x1000) == IMAGINARY)
    {
      printf (" (IMAGINARY)");
    }
  }
  printf ("\n\n\n");
  test19_num1  = packed_string_float_release_memory (test19_num1);
  test19_num2  = packed_string_float_release_memory (test19_num2);
  result_float = packed_string_float_release_memory (result_float);
  

  printf ("********************************************************\n");
  printf ("* TEST 20: Compute 1000 terms of the Fibonacci series. *\n");
  printf ("********************************************************\n");
  state = 0;
  current_fibonacci_term = 0;
  number_of_fibonacci_terms = 1000;
  while (current_fibonacci_term <= number_of_fibonacci_terms)
  {
    printf ("F(%llu) = ", current_fibonacci_term);
    switch (state)
    {
      case 0:
        test20_num1 = packed_string_integer_set_value (test20_num1, "0");
        packed_string_integer_display (test20_num1, 0);
        state = 1;
      break;
      case 1:
        test20_num2 = packed_string_integer_set_value (test20_num2, "1");
        packed_string_integer_display (test20_num2, 0);
        state = 2;  
      break;
      case 2:
        result = packed_string_integer_add (result, test20_num1, test20_num2);
        packed_string_integer_display (result, 0);
        test20_num1 = packed_string_integer_release_memory (test20_num1);
        test20_num1 = packed_string_integer_copy_number (test20_num1, result);
        state = 3;  
      break;
      case 3:
        result = packed_string_integer_add (result, test20_num1, test20_num2);
        packed_string_integer_display (result, 0);
        test20_num2 = packed_string_integer_release_memory (test20_num2);
        test20_num2 = packed_string_integer_copy_number (test20_num2, result);
        result = packed_string_integer_release_memory (result);
        state = 2;  
      break;
      default:
        printf ("\n\n");
        printf ("Oops! Should not be here. state = %d. Exiting now.\n", state);
        exit (EXIT_FAILURE);
      break;
    }     
    printf ("\n");
    current_fibonacci_term++;
  }
}

