1. Algorithm is based on using STL-vector.
2. Algorithm was used to compute Fibonacci[5,000,000] :
http://groups.google.com/groups?selm=an_466658577
http://library.wolfram.com/mathgroup/archive/1999/Apr/msg00296.html
http://groups.google.com/groups?selm=7fn3g7%248f3%241%40nnrp1.dejanews.com
http://library.wolfram.com/mathgroup/archive/1999/Apr/msg00435.html
====================================================
gpp : GNU C++ version 2.95.3 20010315/djgpp (release) (djgpp)
compiled by GNU C version 2.95.3 20010315/djgpp (release).
Windows98
====================================================
====================================================
============== List Of Program Files ===============
The algorithm contains the following files :
1. fib.h template classes
2. fib.c auxiliary functions
3. main.c main program
====================================================
#########################################################
=== File #1 of 3 : fib.h ================================
------------------- C++ code : BEGIN --------------------
// ==============================================================
//
// Copyright (c) 1999-2001 by Alex Vinokur. This work and all works
// derived from it may be copied and modified without any
// restrictions other than that a copy of this copyright notice
// must be included in any copy of this work or any derived work.
//
// ==============================================================
static char id_h[] = "@(#)Author ## "__FILE__" ::: Alex Vinokur";
// ##############################################################
// =============================
// Very Large Fibonacci Numbers
// =============================
//
// FILE : fib.h
//
// AUTHOR : Alex Vinokur
//
// DESCRIPTION :
// Template classes :
// - ClassDesirableLongInt
// - ClassTemplateFibonacci
// - ClassTemplateOneFibonacci
// - ClassDecUnitFibonacci
// - ClassDecUnitOneFibonacci
// - ClassHexUnitFibonacci
// - ClassHexUnitOneFibonacci
//
// DATE VERSION
// ---- -------
// Apr-22-1999 AVF 1.0
// Dec-12-2001 AVF 1.1
//
// ##############################################################
#ifndef __fib_H
#define __fib_H
//###===###===###===###===###===###===###===###===###===###
#include <assert.h>
#include <string>
#include <strstream>
#include <vector>
#include <iomanip>
//#######################################################
//##### PART#1 : TYPEDEFs & DEFINES & CONSTANTS #########
//#######################################################
#define MAX_VALUE(x,y) ((x) > (y) ? (x) : (y))
#define ASSERT(x) assert (x)
#define INFO_MESSAGE
typedef unsigned int uint;
typedef unsigned long ulong;
const ulong Max_Unit_Value_CNS = (ULONG_MAX >> 2);
const uint INFO_period_CNS = 10000;
static const string UNITS_Delimeter_CNS = "";
//#######################################################
//##### PART#2 : DECLARATIONS ###########################
//#######################################################
template <uint EXPO, uint UNIT_BASE>
class ClassDesirableLongInt;
template <uint EXPO, uint UNIT_BASE>
ClassDesirableLongInt<EXPO, UNIT_BASE> operator+ (
const ClassDesirableLongInt<EXPO, UNIT_BASE>&left_i,
const ClassDesirableLongInt<EXPO, UNIT_BASE>&right_i
);
//#######################################################
//##### PART#3 : The ClassDesirableLongInt class ###########
//#######################################################
//#############################
template <uint EXPO, uint UNIT_BASE>
class ClassDesirableLongInt
{
template <uint E1, uint U1>
friend ClassDesirableLongInt<E1, U1> operator+ (
const ClassDesirableLongInt<E1, U1>& left_i,
const ClassDesirableLongInt<E1, U1>& right_i
);
private :
ulong full_base_;
vector <ulong> vector_unit_;
public :
ClassDesirableLongInt ();
ClassDesirableLongInt (ulong unit_value_i);
ClassDesirableLongInt (
const ClassDesirableLongInt<EXPO, UNIT_BASE>& left_i,
const ClassDesirableLongInt<EXPO, UNIT_BASE>& right_i
);
~ClassDesirableLongInt () {}
void set_full_base ();
string getValueComment (ios& show_base_i (ios&)) const;
string getStrValue (ios& show_base_i (ios&)) const;
string getAllInfo (ios& show_base_i (ios&)) const;
uint getSize (ios& show_base_i (ios&)) const;
static uint getSize_S (const string& strValue_i);
uint getTotalUnits () const {return vector_unit_.size ();}
};
//=====================
template <uint EXPO, uint UNIT_BASE>
ClassDesirableLongInt<EXPO, UNIT_BASE> operator+ (
const ClassDesirableLongInt<EXPO, UNIT_BASE>&left_i,
const ClassDesirableLongInt<EXPO, UNIT_BASE>&right_i
)
{
ClassDesirableLongInt<EXPO, UNIT_BASE>
ret_ClassDesirableLongInt_Value;
const ulong max_size_CNS = MAX_VALUE (
left_i.vector_unit_.size (),
right_i.vector_unit_.size ()
);
ulong cur_big_value;
ulong head = 0;
for (ulong theIndex = 0; theIndex < max_size_CNS; theIndex++)
{
ASSERT (head < Max_Unit_Value_CNS);
cur_big_value =
(
(theIndex < left_i.vector_unit_.size ()) ?
left_i.vector_unit_ [theIndex] : 0
)
+
(
(theIndex < right_i.vector_unit_.size ()) ?
right_i.vector_unit_ [theIndex] : 0
)
+
head;
//------------------------
ret_ClassDesirableLongInt_Value.vector_unit_.push_back(cur_big_value%(left_i.full_base_));
ASSERT
(ret_ClassDesirableLongInt_Value.vector_unit_[ret_ClassDesirableLongInt_Value.vector_unit_.size
() - 1] < left_i.full_base_);
//------------------------
head = cur_big_value/(left_i.full_base_);
} // for (ulong theIndex = 0;
ASSERT (ret_ClassDesirableLongInt_Value.vector_unit_.size () ==
max_size_CNS);
if (head)
{
ret_ClassDesirableLongInt_Value.vector_unit_.push_back (head);
}
//======================
return ret_ClassDesirableLongInt_Value;
//======================
} // ClassDesirableLongInt<EXPO, UNIT_BASE> operator+
//=====================
// Constructor-0
template <uint EXPO, uint UNIT_BASE>
ClassDesirableLongInt<EXPO, UNIT_BASE>::ClassDesirableLongInt ()
{
set_full_base ();
}
//=====================
// Constructor-1
template <uint EXPO, uint UNIT_BASE>
ClassDesirableLongInt<EXPO, UNIT_BASE>::ClassDesirableLongInt (
ulong unit_value_i
)
{
set_full_base ();
if (!(unit_value_i < full_base_))
{
cout << "FATAL ERROR : Number Value = "
<< unit_value_i
<< " (too big)"
<< "; It must be less "
<< full_base_
<< "; "
<< __FILE__
<< ", #"
<< __LINE__
<< endl;
exit (1);
}
ASSERT (unit_value_i < full_base_);
vector_unit_.push_back (unit_value_i);
}
//=====================
// Constructor-2
template <uint EXPO, uint UNIT_BASE>
ClassDesirableLongInt<EXPO, UNIT_BASE>::ClassDesirableLongInt (
const ClassDesirableLongInt<EXPO, UNIT_BASE>&left_i,
const ClassDesirableLongInt<EXPO, UNIT_BASE>&right_i
)
{
set_full_base ();
(*this) = left_i + right_i;
}
//=====================
template <uint EXPO, uint UNIT_BASE>
string ClassDesirableLongInt<EXPO, UNIT_BASE>::getStrValue (
ios& show_base_i(ios&)
) const
{
string ret_Value;
strstream tmp_strstream;
ASSERT (
(show_base_i == dec)
||
(show_base_i == hex)
||
(show_base_i == oct)
);
//====================================
if (!vector_unit_.empty ())
{
for (ulong theIndex = (vector_unit_.size () - 1);
theIndex > 0;
theIndex--
)
{
tmp_strstream << show_base_i;
tmp_strstream << vector_unit_ [theIndex];
tmp_strstream << UNITS_Delimeter_CNS;
tmp_strstream << setw (EXPO) << setfill ('0');
}
tmp_strstream << show_base_i;
tmp_strstream << vector_unit_ [0];
}
else
{
tmp_strstream << "NoValue";
}
//====================================
//====================================
tmp_strstream << dec;
tmp_strstream << ends;
ret_Value = tmp_strstream.str(); tmp_strstream.rdbuf()->freeze (0);
return ret_Value;
}
//=====================
template <uint EXPO, uint UNIT_BASE>
string ClassDesirableLongInt<EXPO, UNIT_BASE>::getAllInfo (
ios& show_base_i (ios&)
) const
{
string ret_Value;
strstream tmp_strstream;
string stringValue = getStrValue(show_base_i);
tmp_strstream << stringValue;
tmp_strstream << ";";
tmp_strstream << "\t Size = ";
tmp_strstream << getSize_S (stringValue);
tmp_strstream << getValueComment (show_base_i);
tmp_strstream << ends;
ret_Value = tmp_strstream.str(); tmp_strstream.rdbuf()->freeze (0);
return ret_Value;
}
//=====================
template <uint EXPO, uint UNIT_BASE>
uint ClassDesirableLongInt<EXPO, UNIT_BASE>::getSize (
ios& show_base_i(ios&)
) const
{
return getSize_S (getStrValue (show_base_i));
}
//=====================
// static
template <uint EXPO, uint UNIT_BASE>
uint ClassDesirableLongInt<EXPO, UNIT_BASE>::getSize_S (
const string& strValue_i)
{
int counter = 0;
string::size_type ret_index;
string cur_substr = strValue_i;
if (!UNITS_Delimeter_CNS.empty ())
{ while (!((ret_index = cur_substr.find (UNITS_Delimeter_CNS)) ==
string::npos))
{
counter++;
cur_substr = cur_substr.substr (ret_index + 1);
} // while
}
//======================
return (strValue_i.size () - counter*UNITS_Delimeter_CNS.size ());
//======================
}
//=====================
template <uint EXPO, uint UNIT_BASE>
string ClassDesirableLongInt<EXPO, UNIT_BASE>::getValueComment (
ios& show_base_i(ios&)
) const
{
string ret_Value;
ASSERT (
(show_base_i == dec) |
(show_base_i == hex) |
(show_base_i == oct)
);
ret_Value += " (";
//=======================
if (show_base_i == hex)
{
ret_Value += "hex";
}
if (show_base_i == oct)
{
ret_Value += "oct";
}
if (show_base_i == dec)
{
ret_Value += "dec";
}
//=======================
ret_Value += " digits)";
return ret_Value;
}
//=====================
template <uint EXPO, uint UNIT_BASE>
void ClassDesirableLongInt<EXPO, UNIT_BASE>::set_full_base ()
{
ASSERT (EXPO > 1);
ASSERT (
(UNIT_BASE == 8) ||
(UNIT_BASE == 10) ||
(UNIT_BASE == 16)
);
//==================
full_base_ = 1;
for (ulong theIndex = 1; theIndex <= EXPO; theIndex++)
{
full_base_ *= UNIT_BASE;
if ((full_base_ >= Max_Unit_Value_CNS) || (full_base_ == 0))
{
cout << "FATAL ERROR : EXPO Value = "
<< EXPO
<< " (too big)"
<< "; It must be less "
<< theIndex
<< " (Note! UNIT_BASE == "
<< UNIT_BASE
<< ")"
<< __FILE__
<< ", #"
<< __LINE__
<< endl;
exit (1);
}
ASSERT (UNIT_BASE * ((full_base_/UNIT_BASE) + 1) <
Max_Unit_Value_CNS);
ASSERT (full_base_ != 0);
}
}
//#############################
//#######################################################
//##### PART#4 : The ClassTemplateFibonacci class #####
//#######################################################
//#############################
//=====================
template <uint EXPO, uint UNIT_BASE>
class ClassTemplateFibonacci
{
private :
vector< ClassDesirableLongInt<EXPO, UNIT_BASE> > fib_vector_;
protected :
ClassTemplateFibonacci (int n_i = 0);
public :
string getAllNumbers (ios& show_base_i (ios&)) const;
string getAllSizes (ios& show_base_i (ios&)) const;
virtual ClassDesirableLongInt<EXPO, UNIT_BASE> getFibNumber(int
n_i = 0);
virtual ~ClassTemplateFibonacci () {}
};
//-----------------------
// Constructor
template <uint EXPO, uint UNIT_BASE>
ClassTemplateFibonacci<EXPO, UNIT_BASE>::ClassTemplateFibonacci (int
n_i)
{
getFibNumber (n_i);
}
//-----------------------
template <uint EXPO, uint UNIT_BASE>
ClassDesirableLongInt<EXPO, UNIT_BASE> ClassTemplateFibonacci<EXPO,
UNIT_BASE>::getFibNumber (int n_i)
{
const uint cur_size = fib_vector_.size ();
//========================
if (n_i < 0)
{
cout << "FATAL ERROR : n = "
<< n_i
<< "; "
<< __FILE__
<< ", #"
<< __LINE__
<< endl;
exit (1);
}
for (uint i = cur_size; i <= n_i; i++)
{
switch (i)
{
case 0 :
fib_vector_.push_back (ClassDesirableLongInt<EXPO,
UNIT_BASE>(0));
break;
case 1 :
if (fib_vector_.empty ())
{
fib_vector_.push_back (ClassDesirableLongInt<EXPO, UNIT_BASE>
(0));
}
fib_vector_.push_back(ClassDesirableLongInt<EXPO, UNIT_BASE>
(1));
break;
default :
fib_vector_.push_back (
ClassDesirableLongInt<EXPO, UNIT_BASE> (
getFibNumber (i - 2),
getFibNumber (i - 1)
//fib_vector_ [i - 2],
//fib_vector_ [i - 1]
)
);
break;
} // switch (n_i)
//=============================
#ifdef INFO_MESSAGE
if ((i%INFO_period_CNS == 0) & (i > 0))
{
cerr << "INFO"
<< " ("
<< __FILE__
<< ", Line#"
<< __LINE__
<< ")"
<< " : "
<< " Fib#"
<< i
<< " computed; Total Units = "
<< fib_vector_ [fib_vector_.size () - 1].getTotalUnits ()
<< endl;
}
#endif
//=============================
} // for (int i = cur_size; i <= n_i; i++)
//========================
return fib_vector_ [n_i];
} // ulong ClassTemplateFibonacci::getFibNumber (int n_i)
//-----------------------
template <uint EXPO, uint UNIT_BASE>
string ClassTemplateFibonacci<EXPO, UNIT_BASE>::getAllNumbers (
ios& show_base_i (ios&)
) const
{
string ret_Value;
strstream tmp_strstream;
for (uint i = 0; i < fib_vector_.size (); i++)
{
tmp_strstream << "Fib ["
<< i
<< "] = "
<< fib_vector_ [i].getAllInfo (show_base_i)
<< endl;
}
tmp_strstream << ends;
ret_Value = tmp_strstream.str(); tmp_strstream.rdbuf()->freeze (0);
//==========
return ret_Value;
} // string ClassTemplateFibonacci::getAllNumbers () const
//-----------------------
template <uint EXPO, uint UNIT_BASE>
string ClassTemplateFibonacci<EXPO, UNIT_BASE>::getAllSizes (
ios& show_base_i (ios&)
) const
{
string ret_Value;
strstream tmp_strstream;
for (uint i = 0; i < fib_vector_.size (); i++)
{
tmp_strstream << "Fib [" << i << "] : Size is\t "
<< fib_vector_ [i].getSize (show_base_i)
<< fib_vector_ [i].getValueComment (show_base_i)
<< endl;
}
tmp_strstream << ends;
ret_Value = tmp_strstream.str(); tmp_strstream.rdbuf()->freeze (0);
//==========
return ret_Value;
} // string ClassTemplateFibonacci::getAllSizes () const
//#######################################################
//##### PART#5 : The ClassTemplateOneFibonacci class ##
//#######################################################
//#############################
//=====================
template <uint EXPO, uint UNIT_BASE>
class ClassTemplateOneFibonacci : public ClassTemplateFibonacci<EXPO,
UNIT_BASE>
{
private :
protected :
ClassTemplateOneFibonacci (int n_i = 0) :
ClassTemplateFibonacci<EXPO, UNIT_BASE> (n_i)
{}
public :
ClassDesirableLongInt<EXPO, UNIT_BASE> getFibNumber (int n_i = 0);
~ClassTemplateOneFibonacci () {} };
//-----------------------
template <uint EXPO, uint UNIT_BASE>
ClassDesirableLongInt<EXPO, UNIT_BASE> ClassTemplateOneFibonacci<EXPO,
UNIT_BASE>::getFibNumber (int n_i)
{
vector < ClassDesirableLongInt<EXPO, UNIT_BASE> > one_vector_;
one_vector_.push_back (ClassDesirableLongInt<EXPO, UNIT_BASE> (0));
one_vector_.push_back (ClassDesirableLongInt<EXPO, UNIT_BASE> (1));
one_vector_.push_back (ClassDesirableLongInt<EXPO, UNIT_BASE> (0));
//========================
if (n_i < 0)
{
cout << "FATAL ERROR : n = "
<< n_i
<< "; "
<< __FILE__
<< ", #"
<< __LINE__
<< endl;
exit (1);
}
//========================
for (int theIndex = 0; theIndex < n_i; theIndex++)
{
one_vector_.erase (one_vector_.begin ());;
one_vector_.push_back (one_vector_ [0] + one_vector_ [1]);
#ifdef INFO_MESSAGE
if ((theIndex%INFO_period_CNS == 0) & (theIndex > 0))
{
cerr << "INFO"
<< " ("
<< __FILE__
<< ", Line#"
<< __LINE__
<< ")"
<< " : "
<< " Fib#"
<< theIndex
<< " computed; Total Units = "
<< one_vector_ [2].getTotalUnits ()
<< endl;
}
#endif
}
//========================
return one_vector_ [2];
} // ulong ClassTemplateOneFibonacci::getFibNumber (int n_i)
//#######################################################
//##### PART#6 : The ClassDecUnitFibonacci class ######
//#######################################################
//#############################
//=====================
template <uint EXPO>
class ClassDecUnitFibonacci : public ClassTemplateFibonacci <EXPO, 10>
{
public :
ClassDecUnitFibonacci (int n_i = 0) :
ClassTemplateFibonacci<EXPO, 10> (n_i)
{}
~ClassDecUnitFibonacci () {}
};
//==========================
typedef ClassDecUnitFibonacci<9> ClassFibonacci;
//==========================
//#######################################################
//##### PART#7 : The ClassDecUnitOneFibonacci class ###
//#######################################################
//#############################
//=====================
template <uint EXPO>
class ClassDecUnitOneFibonacci : public ClassTemplateOneFibonacci <EXPO,
10>
{
public :
ClassDecUnitOneFibonacci (int n_i = 0) :
ClassTemplateOneFibonacci<EXPO, 10> (n_i)
{}
~ClassDecUnitOneFibonacci () {}
};
//==========================
typedef ClassDecUnitOneFibonacci<9> ClassOneFibonacci;
//==========================
//#######################################################
//##### PART#8 : The ClassHexUnitFibonacci class ######
//#######################################################
//#############################
//=====================
template <uint EXPO>
class ClassHexUnitFibonacci : public ClassTemplateFibonacci <EXPO, 16>
{
public :
ClassHexUnitFibonacci (int n_i = 0) :
ClassTemplateFibonacci<EXPO, 16> (n_i)
{}
~ClassHexUnitFibonacci () {}
};
//#######################################################
//##### PART#9 : The ClassHexUnitOneFibonacci class ###
//#######################################################
//#############################
//=====================
template <uint EXPO> class ClassHexUnitOneFibonacci : public
ClassTemplateOneFibonacci <EXPO, 16>
{
public :
ClassHexUnitOneFibonacci (int n_i = 0) :
ClassTemplateOneFibonacci<EXPO, 16> (n_i)
{}
~ClassHexUnitOneFibonacci () {}
};
//#######################################################
//##### PART#10 : FUNCTIONS #############################
//#######################################################
bool stringIsDigit (const string& string_i);
bool stringIsNonDigit (const string& string_i);
void printAllFib (
ulong n_i,
bool size_only_i = false,
const string& msg_i = string (),
ios& show_base_i (ios&) = dec
);
void printOneFib (
ulong n_i,
const string& msg_i = string (),
ios& show_base_i (ios&) = dec
);
void printSomeFib (
const vector<ulong>& vect_i,
const string& msg_i = string (),
ios& show_base_i (ios&) = dec
);
int mainFib (int argc, char **argv);
//###===###===###===###===###===###===###===###===###===###
#endif // __fib_H
//###################################################
//############ END OF FILE ##########################
//###################################################
------------------- C++ code : END ----------------------
=== File #1 of 3 : fib.h ================================
#########################################################
=== File #2 of 3 : fib.c ================================
------------------- C++ code : BEGIN --------------------
// ==============================================================
//
// Copyright (c) 1999-2001 by Alex Vinokur. This work and all works
// derived from it may be copied and modified without any
// restrictions other than that a copy of this copyright notice
// must be included in any copy of this work or any derived work.
//
// ==============================================================
static char id[] = "@(#)Author ## "__FILE__" ::: Alex Vinokur";
// ##############################################################
// =============================
// Very Large Fibonacci Numbers
// =============================
//
// FILE : fib.c
//
// AUTHOR : Alex Vinokur
//
// DESCRIPTION :
// Functions :
// - stringIsNonnegativeNumber
// - printAllFib
// - printOneFib
// - printSomeFib
// - printErrorUsageMessage
// - argv_check
// - mainFib
//
// DATE VERSION
// ---- -------
// Apr-22-1999 AVF 1.0
// Dec-12-2001 AVF 1.1
//
// ##############################################################
#include "fib.h"
//###################################################
//############ CONSTANTS ############################
//###################################################
static const string all_num_option_CNS = "--all-num";
static const string size_only_option_CNS = "--size-only";
//###################################################
//############ FUNCTION #############################
//###################################################
//#####################################################
bool stringIsNonnegativeNumber (const string& string_i)
{
ASSERT (!string_i.empty ());
for (ulong theIndex= 0; theIndex < string_i.size (); theIndex++)
{
if (!isdigit (string_i [theIndex]))
{
return false;
}
}
return true;
} // bool stringIsNonnegativeNumber (const string& string_i)
//#####################################################
void printAllFib (
ulong n_i,
bool sizes_only_i,
const string& msg_i,
ios& show_base_i (ios&)
)
{
string print_string;
strstream tmp_strstream;
if (!msg_i.empty())
{
tmp_strstream << endl;
tmp_strstream << "################################" << endl;
tmp_strstream << "###" << "\t" << msg_i << endl;
tmp_strstream << "################################" << endl;
}
if (!sizes_only_i)
{
tmp_strstream << ClassFibonacci (n_i).getAllNumbers (show_base_i);
}
else
{
tmp_strstream << ClassFibonacci (n_i).getAllSizes (show_base_i);
}
tmp_strstream << endl;
tmp_strstream << ends;
print_string = tmp_strstream.str(); tmp_strstream.rdbuf()->freeze (0);
cout << print_string;
} // printAllFib
//#####################################################
void printOneFib (
ulong n_i,
const string& msg_i,
ios& show_base_i (ios&)
)
{
string print_string;
strstream tmp_strstream;
if (!msg_i.empty())
{
tmp_strstream << endl;
tmp_strstream << "################################" << endl;
tmp_strstream << "###" << "\t" << msg_i << endl;
tmp_strstream << "################################" << endl;
}
ClassOneFibonacci f1;
tmp_strstream << ""
<< "Fib#"
<< n_i
<< "\t = "
<< f1.getFibNumber (n_i).getAllInfo (show_base_i)
<< endl;
tmp_strstream << endl;
tmp_strstream << ends;
print_string = tmp_strstream.str(); tmp_strstream.rdbuf()->freeze (0);
cout << print_string;
} // printOneFib
//#####################################################
void printSomeFib (
const vector<ulong>& vect_i,
const string& msg_i,
ios& show_base_i (ios&)
)
{
string print_string;
strstream tmp_strstream;
if (!msg_i.empty())
{
tmp_strstream << endl;
tmp_strstream << "################################" << endl;
tmp_strstream << "###" << "\t" << msg_i << endl;
tmp_strstream << "################################" << endl;
}
ClassFibonacci f1;
for (uint theIndex = 0; theIndex < vect_i.size (); theIndex++)
{
tmp_strstream << ""
<< "Fib#"
<< vect_i [theIndex]
<< "\t = "
<< f1.getFibNumber (vect_i [theIndex]).getAllInfo(show_base_i)
<< endl;
} // for (uint theIndex = 0;
tmp_strstream << endl;
//====================
tmp_strstream << ends;
print_string = tmp_strstream.str(); tmp_strstream.rdbuf()->freeze (0);
cout << print_string;
} // printSomeFib
//#####################################################
//#####################################################
//#####################################################
void printErrorUsageMessage (
int argc,
char **argv
)
{
cout << endl
<< "FATAR ERROR!"
<< endl
<< "============"
<< endl
<< "USAGE : "
<< argv[0]
<< " "
<< all_num_option_CNS
<< " <nonnegative number>"
<< " ["
<< size_only_option_CNS
<< "]"
<< endl
<< " : "
<< argv[0]
<< " <nonnegative number> [<nonnegative number> [<nonnegative
number>] ...]"
<< endl;
}
//#####################################################
bool argv_check (
int argc,
char **argv,
ulong cur_index_i,
ulong& cur_numberValue_o
)
{
//============================
ASSERT (argc >= 2);
ASSERT (cur_index_i >= 1);
//============================
if (!stringIsNonnegativeNumber (string (argv[cur_index_i])))
{
printErrorUsageMessage (argc, argv);
cout << endl
<< "NOT NONNEGATIVE NUMBER : "
<< "argv ["
<< cur_index_i
<< "] = "
<< argv [cur_index_i]
<< endl;
return false;
}
cur_numberValue_o = strtoul (argv[cur_index_i], (char**)NULL, 10);
if (cur_numberValue_o == ULONG_MAX)
{
cout << endl
<< "FATAR ERROR!"
<< endl
<< "============"
<< endl
<< "TOO LARGE VALUE : "
<< "argv ["
<< cur_index_i
<< "] = "
<< argv [cur_index_i]
<< endl;
return false;
}
//=====================
return true;
} // bool argv_check (ulong cur_index_i)
//#####################################################
int mainFib (int argc, char **argv)
{
ulong cur_numberValue;
ulong cur_index;
vector<ulong> vect;
bool size_only_flag = false;
for (int i = 0; i < argc; i++)
{
if (argv[i] == size_only_option_CNS)
{
size_only_flag = true;
}
}
switch (argc)
{
case 0 :
assert (0);
break;
case 1 :
printErrorUsageMessage (argc, argv);
exit (1);
break; // unused
case 2 :
cur_index = 1;
if (!argv_check (argc, argv, cur_index, cur_numberValue))
{
exit (1);
}
printOneFib (cur_numberValue);
break;
case 3 :
case 4 :
if (argv [1] == all_num_option_CNS)
{
if (argc == 4)
{
if (!(argv [3] == size_only_option_CNS))
{
printErrorUsageMessage (argc, argv);
exit (1);
}
}
cur_index = 2;
if (!argv_check (argc, argv, cur_index, cur_numberValue))
{
exit (1);
}
printAllFib (cur_numberValue, size_only_flag);
break;
}
default :
for (int theIndex = 1; theIndex < argc; theIndex++)
{
cur_index = theIndex;
if (!argv_check (argc, argv, cur_index, cur_numberValue))
{
exit (1);
}
vect.push_back (cur_numberValue);
}
printSomeFib (vect);
break;
} // switch (argc)
//=================
return 0;
//=================
} // int mainFib (int argc, char **argv)
//###################################################
//############ END OF FILE ##########################
//###################################################
------------------- C++ code : END ----------------------
=== File #2 of 3 : fib.c ================================
#########################################################
=== File #3 of 3 : main.c ===============================
------------------- C++ code : BEGIN --------------------
// ==============================================================
//
// Copyright (c) 1999-2001 by Alex Vinokur. This work and all works
// derived from it may be copied and modified without any
// restrictions other than that a copy of this copyright notice
// must be included in any copy of this work or any derived work.
//
// ==============================================================
static char id[] = "@(#)Author ## "__FILE__" ::: Alex Vinokur";
// ##############################################################
// =============================
// Very Large Fibonacci Numbers
// =============================
//
// FILE : main.c
//
// AUTHOR : Alex Vinokur
//
// DESCRIPTION : Main program
//
// DATE VERSION
// ---- -------
// Apr-22-1999 AVF 1.0
// Dec-12-2001 AVF 1.1
//
// ##############################################################
#include "fib.h"
//###################################################
//###################################################
//###################################################
//==============================
int main (int argc, char **argv)
{
return mainFib (argc, argv);
}
//###################################################
//############ END OF FILE ##########################
//###################################################
------------------- C++ code : END ----------------------
=== File #3 of 3 : main.c ===============================
--------------- Running (sample) : BEGIN ----------------
> a.exe 12
Fib#12 = 144; Size = 3 (dec digits)
> a.exe 7 35 12 93 5
Fib#7 = 13; Size = 2 (dec digits)
Fib#35 = 9227465; Size = 7 (dec digits)
Fib#12 = 144; Size = 3 (dec digits)
Fib#93 = 12200160415121876738; Size = 20 (dec digits)
Fib#5 = 5; Size = 1 (dec digits)
> a.exe --all-num 12
Fib [0] = 0; Size = 1 (dec digits)
Fib [1] = 1; Size = 1 (dec digits)
Fib [2] = 1; Size = 1 (dec digits)
Fib [3] = 2; Size = 1 (dec digits)
Fib [4] = 3; Size = 1 (dec digits)
Fib [5] = 5; Size = 1 (dec digits)
Fib [6] = 8; Size = 1 (dec digits)
Fib [7] = 13; Size = 2 (dec digits)
Fib [8] = 21; Size = 2 (dec digits)
Fib [9] = 34; Size = 2 (dec digits)
Fib [10] = 55; Size = 2 (dec digits)
Fib [11] = 89; Size = 2 (dec digits)
Fib [12] = 144; Size = 3 (dec digits)
> a.exe --all-num 12 --size-only
Fib [0] : Size is 1 (dec digits)
Fib [1] : Size is 1 (dec digits)
Fib [2] : Size is 1 (dec digits)
Fib [3] : Size is 1 (dec digits)
Fib [4] : Size is 1 (dec digits)
Fib [5] : Size is 1 (dec digits)
Fib [6] : Size is 1 (dec digits)
Fib [7] : Size is 2 (dec digits)
Fib [8] : Size is 2 (dec digits)
Fib [9] : Size is 2 (dec digits)
Fib [10] : Size is 2 (dec digits)
Fib [11] : Size is 2 (dec digits)
Fib [12] : Size is 3 (dec digits)
--------------- Running (sample) : END ------------------
===========================
Alex Vinokur
mailto:ale...@bigfoot.com
mailto:ale...@dr.com
http://up.to/alexvn
http://go.to/alexv_math
===========================