#include <iostream>
#include <chrono>
#include <fmt/format.h>
#include "InfInt.h"
// templates
template <typename T>
long highestSubscript{1};
template <typename T>
T evenSubscriptFib{0};
template <typename T>
T oddSubscriptFib{1};
// template for recursive function that calculates a pair of Fibonacci numbers
template <typename T>
void fibonacciVoid(long subscript)
{
if (subscript > highestSubscript<T>) {
fibonacciVoid<T>(subscript - 2); // recursion step
highestSubscript<T> += 2;
evenSubscriptFib<T> += oddSubscriptFib<T>;
oddSubscriptFib<T> += evenSubscriptFib<T>;
}
}
// template for Fibonacci function
template <typename T>
T& fibonacci(long subscript)
{
if (subscript < highestSubscript<T> - 1) {
highestSubscript<T> = 1.0;
evenSubscriptFib<T> = 0;
oddSubscriptFib<T> = 1;
}
fibonacciVoid<T>(subscript);
if (subscript % 2)
return oddSubscriptFib<T>;
else
return evenSubscriptFib<T>;
}
using namespace std;
using namespace std::chrono;
using fibonacciType1 = long;
using fibonacciType2 = InfInt;
// This function is a slightly modified version of the function provided
// by Deitel & Associates, Inc.
fibonacciType1 fibonacci(long number = 0) {
if ((0 == number) || (1 == number)) {
return number;
}
else {
return fibonacci(number - 1) + fibonacci(number - 2);
}
}
int main() {
int sentinel{-1};
cout << fmt::format(
"Enter a sequence of increasing Fibonacci indicies and {} to stop input.\n",
sentinel);
// Section 1
fibonacciType1 evenSubscriptFib{0};
fibonacciType1 oddSubscriptFib{1};
int highestSubscript{1};
int n;
while (
cin >> n
,
sentinel != n) {
cout << n << endl;
while(true) {
if (highestSubscript - 1 == n) {
cout << evenSubscriptFib << endl;
break;
}
if (highestSubscript == n) {
cout << oddSubscriptFib << endl;
break;
}
evenSubscriptFib += oddSubscriptFib;
oddSubscriptFib += evenSubscriptFib;
highestSubscript += 2;
}
}
// Section 2
// use the next line as is to capture the start time of a period of runLimit seconds
time_point<steady_clock> start{steady_clock::now()};
const int runLimit{4}; // generate Fibonacci numbers for runLimit more seconds
time_point<steady_clock> endTime{runLimit*1s + start}; // calculate end time
do {
fibonacci<fibonacciType2>(++highestSubscript);
} while(steady_clock::now() < endTime); // true if endTime has not been reached yet
cout << highestSubscript << endl;
return highestSubscript % 256;
}
This C++ code appears to be part of a practice activity for a midterm exam. It includes a variety of techniques, such as function templates, recursion, timing, and arbitrary-precision arithmetic through the InfInt
library. The program calculates Fibonacci numbers and times the duration of these calculations. Here’s a breakdown of how each part of the code works:
Includes and Namespaces:
#include <iostream>
: Includes the standard C++ header for I/O stream objects (e.g.std::cin
,std::cout
).#include <chrono>
: Includes the header for date and time utilities.#include <fmt/format.h>
: Includes the header for thefmt
library, which provides utilities for text formatting.#include "InfInt.h"
: Presumably includes the header for an arbitrary-precision integer class (InfInt
), which is not a standard library. This must be a third-party or custom library for working with integers of an unlimited size.using namespace std;
: Brings all standard namespace members into scope, allowing the program to omitstd::
prefix.using namespace std::chrono;
: Brings allchrono
namespace members into scope.
Global Templates and Variables:
- The code declares template global variables
highestSubscript
,evenSubscriptFib
, andoddSubscriptFib
. These keep track of the highest calculated Fibonacci index and the values of the most recent even and odd Fibonacci numbers, respectively.
Recursive Template Function fibonacciVoid
:
fibonacciVoid
: A recursive template function that calculates a pair of Fibonacci numbers for a given subtype T. It uses the template global variables to store its state across recursion.
Non-recursive Template Function fibonacci
:
fibonacci
: A template function that returns a reference to the Fibonacci number at the given index. It corrects the global state if the requested index is lower than the currently stored highest subscript and callsfibonacciVoid
to potentially update the stored Fibonacci numbers.
Function fibonacci
(Overloaded version):
- This is an overloaded and non-templated version of the
fibonacci
function, which uses simple recursion to calculate the Fibonacci number. This version will be inefficient for large indices due to the number of recursive calls it generates.
Main Function:
The main
function is divided into two sections:
Section 1:
- This section reads a sequence of increasing Fibonacci indices from the standard input and prints the corresponding Fibonacci number for each index. It uses an iterative approach to calculate Fibonacci numbers. When the sentinel value (set to -1) is entered, the input loop stops.
Section 2:
- This part demonstrates timing by calculating Fibonacci numbers for a period defined by
runLimit
(4 seconds in this case) using thefibonacciType2
(InfInt
) type. It uses thechrono
library to keep track of the time passed. - The
steady_clock
is used to measure time intervals.
Return Value:
- The program returns
highestSubscript % 256
, wherehighestSubscript
will end up being the last subscript requested during the timed calculation section. The modulo operation ensures that the return value is within the range of anunsigned char
(0 to 255).
Points to Note:
- There appears to be a conceptual conflict between the global template variables and the local variables within the
main
function that share the same names but different types. - The
InfInt
version uses template global variables for state, while the simple recursive version does not. - The code uses the
fmt
library for formatted output, which is a modern and efficient way to format strings in C++ (if this version is C++20 or later,{fmt}
is part of the standard library as<format>
). - The program may not run properly because of the duplicated global variables and function names; this ambiguity might cause errors during compilation or runtime.
- The untemplated version of the
fibonacci
function that utilizes simple recursion is not involved in the timing part of the main function (Section 2). It might be there for comparison purposes or for a different exercise.
This overview provides an insight into what the code is doing and how different components work. However, for a real application, one should handle possible conflicts and redundancy within the code to make it more robust.