What is wrong in this code? (Largest and Smallest element in array) - c++

This is my code in C++. When I am taking input {11 10 5 6 7} in the array, Every time it's giving output smallest as 0. But giving correct output to the other inputs.
#include<bits/stdc++.h>
using namespace std;
int main() {
int a[100000];
int large, small;
int n;
cin >> n;
for (int j = 0; j < n; j++) {
cin >> a[j];
}
for (int j = 0; j < n; j++) {
cout << a[j] << " ";
}
large = small = a[0];
for (int i = 1; i <= n; i++) {
if (a[i] < small) {
small = a[i];
}
if (a[i] > large) {
large = a[i];
}
}
cout << "Smallest is " << small << endl;
cout << "Largest is " << large << endl;
}

You have three loops, two of them run while i<n and the third one while i<=n. And then it uses a[n] item. How do you think what the value of a[n] is?

You were asking:
What is wrong in my code
Let me first answer this question and then we will refactor and optimize it.
So, let's list up the findings
#include<bits/stdc++.h> is non-compliant C++ code. It should never be used. It will run only on selected compilers
using namespace std; should not be used. Always use fully qualified names
C-Style arrays, like a[100000] should not be used in C++. Always use dedicated C++ containers like std::array or std::vector or others. In your case, the size of the array is determined at runtime. So, std::vector must be used
the “100000” is a magic number. Why 100000? Why not 500?. And what happens if the user enters 200000 as array size. Then the program will most likely crash
Use always meaningful variable names. Something like “n” will not be understood. The variable “arraySize” would be understood.
Variables shall always be initialized. And only defined, where they are used and not in the beginning of the program
Input should be verified (cin >> n). What will happen, if the user enters ‘x’ and not ‘5’. Remember, you do not initialize variable n.
large and small must be initialized with the smallest / largest value that the relevant data type can hold. Otherwise the result will always be wrong
array indices start with 0 and not with 1. So, your for loop will fail. The result will be wrong. And you used <=n. So, you will access an out of bounds value.
No need to use endl with cout. ‘\n’ will be sufficient
Then, from the design point of view. You do not need an array at all. You can make all checks immediately, directly after reading the next value.
Anyway, let us make the first step of refactoring. And ths adopted to your programming style. We will
still use C-Style arrays and dynamically allocate the memory
even use raw pointers for owned memory and new. Please note. This should not be done!
correct the bugs
use INT_MIN and INT_MAX
use meaningful variable names and comments
Please see the first refactoring step:
#include <iostream>
#include <climits>
int main() {
// Get the array size from the user and validate the input
unsigned int arraySize{};
if ((std::cin >> arraySize) and (arraySize > 0u)) {
// Now, allocate the memory for the array
int* const array = new int[arraySize]();
// Read all values from user into the just allocated array
for (unsigned int index = 0; index < arraySize; ++index) {
// Read value and check, if OK. If not, value will be 0
if (not (std::cin >> array[index])) std::cerr << "\nError: Wrong value\n";
}
// Now we set up the result values, always with the opposite maximum/minimum
int maxValueInArray = INT_MIN;
int minValueInArray = INT_MAX;
// Iterate over all values and check for min and maximum
for (unsigned int index = 0; index < arraySize; ++index) {
// Compare and assign potential new values
if (array[index] < minValueInArray) minValueInArray = array[index];
if (array[index] > maxValueInArray) maxValueInArray = array[index];
}
// Free the allocated memory. We do not need it any longer
delete [] array;
// Show result to user
std::cout << "Smallest is " << minValueInArray << '\n';
std::cout << "Largest is " << maxValueInArray << '\n';
}
else std::cerr << "\nError while reading array size\n\n";
}
So, next, let’s go a little bit more into the direction C++.
We will get rid of raw pointers, new and will use the correct limit values.
#include <iostream>
#include <limits>
#include <memory>
int main() {
// Get the array size from the user and validate the input
unsigned int arraySize{};
if ((std::cin >> arraySize) and (arraySize > 0u)) {
// Now, allocate the memory for the array
std::unique_ptr<int[]> array = std::make_unique<int[]>(arraySize);
// Read all values from user into the just allocated array
for (unsigned int index = 0; index < arraySize; ++index) {
// Read value and check, if OK. If not, value will be 0
if (not (std::cin >> array[index])) std::cerr << "\nError: Wrong value\n";
}
// Now we set up the result values, always with the opposite maximum/minimum
int maxValueInArray = std::numeric_limits<int>::min();
int minValueInArray = std::numeric_limits<int>::max();
// Iterate over all values and check for min and maximum
for (unsigned int index = 0; index < arraySize; ++index) {
// Compare and assign potential new values
if (array[index] < minValueInArray) minValueInArray = array[index];
if (array[index] > maxValueInArray) maxValueInArray = array[index];
}
// Show result to user
std::cout << "Smallest is " << minValueInArray << '\n';
std::cout << "Largest is " << maxValueInArray << '\n';
}
else std::cerr << "\nError while reading array size\n\n";
}
A little bit better. Now we get rid of the whole manual memory allocation and use a std::vector, which is by far better. And we will use range based for loops, which will make our life simpler:
#include <iostream>
#include <limits>
#include <vector>
int main() {
// Get the array size from the user and validate the input
unsigned int arraySize{};
if ((std::cin >> arraySize) and (arraySize > 0u)) {
// Now, allocate the memory for the array
std::vector<int> data(arraySize, 0);
// Read all values from user into the just allocated array
for (int& value : data) {
// Read value and check, if OK. If not, value will be 0
if (not (std::cin >> value)) std::cerr << "\nError: Wrong value\n";
}
// Now we set up the result values, always with the opposite maximum/minimum
int maxValueInArray = std::numeric_limits<int>::min();
int minValueInArray = std::numeric_limits<int>::max();
// Iterate over all values and check for min and maximum
for (const int& value : data) {
// Compare and assign potential new values
if (value < minValueInArray) minValueInArray = value;
if (value > maxValueInArray) maxValueInArray = value;
}
// Show result to user
std::cout << "Smallest is " << minValueInArray << '\n';
std::cout << "Largest is " << maxValueInArray << '\n';
}
else std::cerr << "\nError while reading array size\n\n";
}
And last but not least, we will get of the whole array/vector stuff. It is not needed.
#include <iostream>
#include <limits>
int main() {
// Get the number of values to check from the user and validate the input
unsigned int numberOfValues{};
if ((std::cin >> numberOfValues) and (numberOfValues > 0u)) {
// Now we set up the result values, always with the opposite maximum/minimum
int maxValueInArray = std::numeric_limits<int>::min();
int minValueInArray = std::numeric_limits<int>::max();
// Read all values from user and check them immediately
for (unsigned int i{}; i<numberOfValues; ++i) {
// Read value and check, if OK. If not, value will be 0
int value{};
if (not (std::cin >> value)) std::cerr << "\nError: Wrong value\n";
// Compare and assign potential new values
if (value < minValueInArray) minValueInArray = value;
if (value > maxValueInArray) maxValueInArray = value;
}
// Show result to user
std::cout << "Smallest is " << minValueInArray << '\n';
std::cout << "Largest is " << maxValueInArray << '\n';
}
else std::cerr << "\nError while reading number of values\n\n";
}

On the third loop it will be
for(int i=0;i<n;i++)

Related

Arrays and Pointers +Errors

Here is the assignment:
Your goal is to write a program that displays a series of whole numbers from input in reverse order. Your
program will prompt the user for the number of values in this list, which it will use as the size for a dynamic
array declared after this prompt.
The array size is unknown, the value is the pointer, and the sub has to be assigned before the loop.
Here are the steps:
Declare variables, but don't "allocate the memory the memory for the pointer yet". Do this after prompting the user to enter the values.
Prompt user to enter the numbers of values to be listed. (There has to be a message for the user in case they enter a negative number). Then use the keyword new for the pointer.
Prompt the user to enter the values
Display the values in reverse.
Use the keyword delete for the dynamic array.
While I'm trying to run the program, the error was:
error: ISO C++ forbids comparison between pointer and integer [-fpermissive]
for(int sub = 0; sub < size; size--)
--------------------------------------^
error: lvalue required as decrement operand
for (int sub = 0; sub > size; size--)
------------------------------------------------------^
Also, I am not sure what the keyword new does.
#include <iostream>
using namespace std;
int main()
{
int size, array;
cout << "How many values would you like to enter? ";
cin >> array;
int value;
int *array = new int[size];
if (size > 0)
{
for (int sub = 0; sub < size; size++)
{
cout << "Enter value #" << size << ": ";
cin >> value;
}
while (size > 0);
}
else
{
while (size < 0)
{
cout << "Size must be positive." << endl;
cout << "How many values would you like to enter? ";
cin >> size;
}
}
cout << "Here are the values you entered in reverse order: \n";
for (int sub = size - 1; sub >= 0; size--)
{
cout << "Value #" << size << " :" << value << endl;
}
delete[] array;
return 0;
}
PS: I know size is supposed to be unknown, but I've encountered another error saying
storage size of ‘size’ isn’t known
So, I add numbers to avoid that error.
Edit:So I changed the code thanks to #MikeCAT, but this error said terminate called after throwing an instance of 'std::bad_array_new_length what(): std::bad_array_new_length. This was because I enter a negative number for the size, which was supposed to happen for the if statement. Also, I need the size to start at 1 after the user enters how many values they want to enter, but the size always starts at the number that was entered.
As the assignment says, you should
Read a value
Allocate a dynamic array using the value read as its size
Read the numbers for the array
#include <iostream>
int main(void) {
// read a number (size of a dynamic array)
int numElements;
std::cin >> numElements;
// allocate a dynamic array
int *array = new int[numElements];
// read values for the dynamic array
for (int i = 0; i < numElements; i++) {
std::cin >> array[i];
}
// print the values in reversed order
for (int i = numElements - 1; i >= 0; i--) {
std::cout << array[i] << '\n';
}
// de-allocate the array
delete[] array;
// exit normally
return 0;
}
Error handling and non-essensial messages are omitted. Try adding them.

Passing value from one function to another C++

I'm writing two functions: one of them is for "filling" array with random values and int the second function I have to use the same array, choose one row and find the min element of that row.
But the problem is that I don't know how to pass values from one function to another.
Here is my code:
#include <cstdlib>
#include <ctime>
#include <iostream>
using namespace std;
void fillarray(int arr[5][5], int rows, int cols) {
cout << "Static Array elements = \n\n" << flush;
for(int i = 0; i < rows; ++i) {
cout << "Row " << i << " ";
for(int j = 0; j < cols; ++j) {
arr[i][j] = rand() % 10;
cout << arr[i][j] << " " << flush;
}
cout << endl;
}
cout << " \n\n";
}
void minarray(int a, void fillarray) { // don't know what to write here
there:
int min = INT_MAX; // Value of INT_MAX is 2147483648.
if(a > 4) {
cout << "Invalid input! " << endl;
goto there;
}
for(int counter = 0; counter < 5; ++counter) {
if(arr[a][counter] < min) min = arr[a][counter];
}
cout << "Minimum element is " << min << endl;
}
int main() {
int z;
srand(time(NULL));
const int rows = 5;
const int cols = 5;
int arr[rows][cols];
fillarray(arr, rows, cols);
cout << "Enter the number of row: ";
cin >> z;
minarray(z, fillarray)
system("PAUSE");
}
For starters the function fillarray has redundant parameter cols because this number is known from the declaration of the first parameter int arr[5][5].
Th function can be declared like
void fillarray(int arr[5][5], int rows )
You could supply the parameter cols in case when not the whole array is filled in the function.
You already filled the array by this call
fillarray ( arr, rows, cols );
The function performed its task. So there is no need to reference the function one more time as you are trying
minarray(z, fillarray)
The function minarray can be declared either like
void minarray( const int arr[], size_t n );
and called like
minarray( arr[z], cols );
with a preliminary check that z is less than 5.
Or it can be declared like
void minarray( const int arr[][5], size_t n, size_t row );
and called like
minarray( arr, rows, z );
Pay attention to that there is the standard algorithm std::min_element that allows to find minimum element in an array. And to fill an array with values you can use the standard algorithm std::generate.
And each function should do only one task. For example the function fillarray should silently fill the array with values. To output the array you could write a separate function.
I'm not sure this even compiles, but i'm guessing you want to pass int arr[x][y] from the fill Array function to the minArray function. To do that you first need to include arr as a parameter of minArray. From there you need to pass it by reference. Then, you can call minArray from fillArray.
What you need to do is call fillarray to fill your array. So it would look like
fillarray(arr, rows, cols);
Just like you have so far. Now, you have array arr all filled in. minarray doesn't care how that happened. So don't pass it your filler method. Pass it the array.
minarray(cols, arr[z]);
You don't need to pass the entire array -- just the row in question. You're also passing the width.
And change the definition of minarray:
void minarray(int length, int[] array)
Now, your minarray itself needs changes. First, get rid of the if-check. You don't need to pass a row number now, but you do need the number of columns passed as length.
Then your for loop looks like:
for (int index = 0; index < length; ++index) {
if (array[index] < min) {
min = array[index];
}
}
So, to summarize:
Main declares the data and calls your two methods.
fillarray populates the array. It is called from main the way you already have.
minarray prints the minimum on a single line. It is also called from main, passing in the array, not the method that filled it.
You have one more issue, however. fillarray hardcodes the array size as 5x5, but main uses constants defined. I'd move those contents to the top of the file and use them in both places.
Move to the top, below any #includes:
const int rows = 5;
const int cols = 5;
Define fillarray:
void fillarray(int arr[rows][cols]) {
And when you call it from main:
fillarray(arr);
I'll let the other answers answer your question and concentrate on the code around your goto that you asked about in the comments.
In main you have this:
cout << "Enter the number of row: ";
cin >> z;
minarray(z, fillarray)
In minarray you have this:
void minarray(int a, void fillarray) { // don't know what to write here
there:
int min = INT_MAX; // Value of INT_MAX is 2147483648.
if(a > 4) {
cout << "Invalid input! " << endl;
goto there;
}
First, there's absolutely no reason to use goto. You could do this:
void minarray(int a, void fillarray) { // don't know what to write here
int min = INT_MAX; // Value of INT_MAX is 2147483648.
while(a > 4) { // loop for as long as "a > 4"
cout << "Invalid input! " << endl;
}
Removing the goto made the bug rather apparent. a will never change inside the loop, so it'll just print Invalid input! forever if you give it invalid input. An alternative would be to validate the input when you actually get the input from the user (in main):
while(true) { // loop forever
cout << "Enter the number of row: ";
if(cin >> z) { // check that the user inputs an int
if(z<0 || z>4) // validate the input
cout << "Invalid input!\n";
else
break; // we got valid input, break out of the while loop
} else { // user did not input an int
std::cout << "input failed - aborting\n";
return 1; // return from main to exit the program
}
} // if the program reaches this point, it'll ask the user for input again
// and that will only happen if the user gives it an int that is <0 or >4

I'm having trouble in C++ geting input from a user in a function, adding to an array, and printing that array

I'm learning c++ and I'm trying to ask the user to input 4 numbers in a function, and then simply print the array.
int getFourNums();
int main(int argc, char** argv){
int getNums;
getNums = getFourNums();
cout << "The array is: " getNums << endl;
}
int getFourNums(){
int i;
int myArray[4];
cout << "Enter 4 nums: ";
for(i = 0; i < 4; i++){
cin >> myArray[i];
}
return myArray[i];
As of now, it's letting me get the four numbers, but the result that's printing is "The array is: 0." I'm not quite sure why the array is seemingly not populating.
Your fundamental problem is that int getFourNums() can only return a single integer, not an array of them. The next problem is that functions cannot return raw arrays for historical reasons. Your choices are to return a std::array, a struct containing the array, pass the array by reference into the function, or return a std::vector. My preference for this application is a std::vector - it is flexible, and although not quite as efficient as std::array, you should probably default to std::vector unless you have a good reason otherwise. Your getNums code would then look like:
std::vector<int> getFourNums() {
std::vector<int> result;
cout << "Enter 4 nums: ";
for(int i = 0; i < 4; i++){
int v;
cin >> v;
result.push_back(v);
}
return result;
}
To print the vector, see this question. My personal preference would be a range-based for loop over the vector; your tastes may vary.
One issue in your code is that a loop like
for(i = 0; i < 4; i++){
cin >> myArray[i];
}
will end up with i==4. Hence, return myArray[i] will exceed array bounds and/or access an uninitialised value then and yield undefined behaviour.
The main issue, however, is that in C++ you'll follow a very different approach and use collection types like std::vector instead of plain arrays. See the following code illustrating this. Hope it helps.
#include <vector>
#include <iostream>
std::vector<int> getFourNums(){
int val;
std::vector<int> result;
cout << "Enter 4 nums: ";
for(int i = 0; i < 4; i++){
cin >> val;
result.push_back(val);
}
return result;
}
int main(int argc, char** argv){
std::vector<int> fourNums = getFourNums();
for (auto i : fourNums) {
cout << i << endl;
}
}
int getFourNums() will only let you return one int, not the whole array and return myArray[i]; is out of bounds since i == 4. You can only use the range [0,3] as indices for your array. Here's a reworked version with comments in the code.
#include <iostream>
#include <vector>
// don't do "using namespace std;" since it includes
// a lot of stuff you don't need.
// Here's a function that will return a vector of int's
// It'll behave much like a C style array
// but can have variable length and you can use
// a lot of standard functions on it.
std::vector<int> getNums(size_t count) {
// The "array" we'll return with "count" number of
// default constructed int:s (they will all be 0):
std::vector<int> myArray(count);
std::cout << "Enter " << count << " nums: ";
// A range based for loop that will go through
// all int:s in "myArray". "num" will be
// a reference to each int in the vector which
// means that if you change the value of "num",
// you'll actually change the value in the vector.
for(int& num : myArray) {
// read values into the int currently
// referenced by num
std::cin >> num;
}
// return the vector by value
return myArray;
}
// Put main() last so you don't have to forward declare the functions
// it uses
int main() {
// call getNums with the value 4 to read 4 int:s
std::vector<int> Nums = getNums(4);
std::cout << "The array is:";
// print each int in the vector. There's no need to use
// a reference to the int:s here since we won't be changing
// the value in the vector and copying an int is cheap.
for(int num : Nums) {
std::cout << " " << num;
}
// std::endl is rarely good when you only want to output a newline.
// It'll flush the buffer with is costly.
// Make a habit of using "\n" in most cases.
std::cout << "\n";
}
I see that you want to return entire array but just look at your return type:
int getFourNums()
You're returning an integer right? In this situation the returned integer is always myArray[4]. Be aware that it's an integer value, you're returning something that doesn't belong to you actually!
So what to do? I suggest you to pass your array to function like this:
void getFourNums(int myArray[]){
int i;
cout << "Enter 4 nums: ";
for(i = 0; i < SIZE; i++){
cin >> myArray[i];
}
}
Now you filled your array. How to print your array then? We can't simply give our array name and tell cout to print it like you did (you couldn't actually!). Nothing magical here. We're going to print your array's element one by one:
void printFourNumbers(int array[])
{
for(int i = 0 ; i < SIZE ; ++i)
{
cout << array[i] << endl;
}
}
Finally whole code looks like this:
#include <iostream>
using namespace std;
const int SIZE = 4;
void getFourNums(int myArray[]);
void printFourNumbers(int array[]);
int main(int argc, char** argv){
int myArray[SIZE];
getFourNums(myArray);
printFourNumbers(myArray);
}
void getFourNums(int myArray[]){
int i;
cout << "Enter 4 nums: ";
for(i = 0; i < SIZE; i++){
cin >> myArray[i];
}
}
void printFourNumbers(int array[])
{
for(int i = 0 ; i < SIZE ; ++i)
{
cout << array[i] << endl;
}
}

Creating an array

write a program that let's the user enter 10 numbers into an array. The program should then display the largest number as and the smallest number stored in the array.
I am very confused on this question that was on a previous exam and will be on the final. Any help would be appreciated! This is what I had on the test and got 3/15 points, and the code was almost completely wrong but I can post what I had if necessary, thanks! For creating the array, i can at least get that started, so like this?
#include <iostream>
using namespace std;
int main()
{
int array(10); // the array with 10 numbers, which the user will enter
cout << "Please enter 10 numbers which will be stored in this array" << endl;
cin >> array;
int smallest=0; //accounting for int data type and the actual smallest number
int largest=0; //accounting for int data type and the actual largest number
//-both of these starting at 0 to show accurate results-
And then on my test, i started using for loops and it got messy from there on out, so my big problem here i think is how to actually compare/find the smallest and largest numbers, in the best way possible. I'm also just in computer science 1 at university so we keep it pretty simple, or i like to. We also know binary search and one other search method, if either of those would be a good way to use here to write code for doing this. Thanks!
Start by declaring an array correctly. int array(10) initializes a single integer variable named array to have the value 10. (Same as saying int array = 10)
You declare an array of 10 integers as follows:
int array[10];
Anyway, two simple loops and you are done.
int array[10];
cout << "Enter 10 numbers" << endl;
for (int x = 0; x < 10; x++)
{
cin >> array[x];
}
int smallest=array[0];
int largest=array[0];
for (int x = 1; x < 10; x++)
{
if (array[x] < smallest)
{
smallest = array[x];
}
else if (array[x] > largest)
{
largest = array[x];
}
}
cout << "Largest: " << largest << endl;
cout << "Smallest: " << smallest << endl;
You can actually combine the two for loops above into a single loop. That's an exercise in an optimization that I'll leave up to you.
In this case, you don't actually have to do a binary search, or search the array. Since you will be receiving the input directly from the user, you can keep track of minimum and maximum as you encounter them, as show below. You know the first number you receive will be both the min and max. Then you compare the next number you get with those ones. If it's bigger or smaller, you store it as the max or min respectively. And then so on. I included code to store the number in an array, to check errors and to output the array back to the user, but that's probably not necessary on an exam due to the limited time. I included it as a little bit of extra info for you.
#include <cctype> // required for isdigit, error checking
#include <cstdlib> // required for atoi, convert text to an int
#include <iostream> // required for cout, cin, user input and output
#include <string> // required for string type, easier manipulation of text
int main()
{
// The number of numbers we need from the user.
int maxNumbers = 10;
// A variable to store the user's input before we can check for errors
std::string userInput;
// An array to store the user's input
int userNumbers[maxNumbers];
// store the largest and smallest number
int max, min;
// Counter variables, i is used for the two main loops in the program,
// while j is used in a loop for error checking
int i;
unsigned int j;
// Prompt the user for input.
std::cout << "Please enter " << maxNumbers << " numbers: " << std::endl;
// i is used to keep track of the number of valid numbers inputted
i = 0;
// Keep waiting for user input until the user enters the maxNumber valid
// numbers
while (i < maxNumbers)
{
// Get the user's next number, store it as string so we can check
// for errors
std::cout << "Number " << (i+1) << ": ";
std::cin >> userInput;
// This variable is used to keep track of whether or not there is
// an error in the user's input.
bool validInput = true;
// Loop through the entire inputted string and check they are all
// valid digits
for (j = 0; j < userInput.length(); j++)
{
// Check if the character at pos j in the input is a digit.
if (!isdigit(userInput.at(j)))
{
// This is not a digit, we found an error so we can stop looping
validInput = false;
break;
}
}
// If it is a valid number, store it in the array of
// numbers inputted by the user.
if (validInput)
{
// We store this number in the array, and increment the number
// of valid numbers we got.
userNumbers[i] = atoi(userInput.c_str());
// If this is the first valid input we got, then we have nothing
// to compare to yet, so store the input as the max and min
if (i == 0)
{
min = userNumbers[i];
max = userNumbers[i];
}
else {
// Is this the smallest int we have seen?
if (min < userNumbers[i])
{
min = userNumbers[i];
}
// Is this the largest int we have seen?
if (max < userNumbers[i])
{
max = userNumbers[i];
}
}
i++;
}
else
{
// This is not a valid number, inform the user of their error.
std::cout << "Invalid number, please enter a valid number." << std::endl;
}
}
// Output the user's numbers to them.
std::cout << "Your numbers are: " << userNumbers[0];
for (i = 1; i < maxNumbers; i++)
{
std::cout << "," << userNumbers[i];
}
std::cout << "." << std::endl;
// Output the min and max
std::cout << "Smallest int: " << min << std::endl;
std::cout << "Largest int: " << max << std::endl;
return 0;
}

Fibonacci series in C++ can't get more than 47 numbers

I designed this program that can print the Fibonacci Series (series[i] = series[i-1] + series[i-2]) but i can't get more than 47 numbers because the 48th they become negative and strange numbers (i think this happens when the list is out of range or the item is null):
#include <iostream>
#include <vector>
using namespace std;
int main ()
{
int length;
string again = "";
do {
cout << "Enter the length you want in your sequence: ";
cin >> length;
vector<int> series(length);
for (int n=0; n<=1; n++) series[n] = n;
for (int number=2; number<=length; number++) {
series[number] = series[number-1] + series[number-2];
}
for (int i=0; i<length; i++) cout << series[i] << " ";
cout << endl << "Do it again ? <y/n> ";
cin >> again;
cout << endl;
} while (again == "y");
}
EDIT:
"Improved" code:
#include <iostream>
#include <vector>
#include <string>
std::vector<int> fibonacci (int length)
{
std::vector<int> series(length);
series[0] = 0;
series[1] = 1;
for (int num=2; num<length; num++) {
series[num] = series[num-1] + series[num-2];
}
return series;
}
int main ()
{
std::string again;
do {
std::cout << "Enter how many numbers you want in your series: ";
int length;
std::cin >> length;
std::vector<int> series(length);
series = fibonacci(length);
for (int n=0; n<length; n++) std::cout << series[n] << " ";
std::cout << "\nDo it again <y/n> ? ";
std::cin >> again;
std::cout << std::endl;
} while (again == "y");
}
When you get to the 47th value, the numbers go out of int range. The maximum int value is 2,147,483,647 and the 46th number is just below at 1,836,311,903. The 47th number exceeds the maximum with 2,971,215,073.
Also, as LeonardBlunderbuss mentioned, you are exceeding the range of the vector with the for loop that you have. Vectors start with 0, and so by having number<=length; the range+1 element will be called. The range only goes up to length-1.
You are encountering integer overflow, meaning that you are trying to calculate a number that is outsize of the bounds of INT_MAX and INT_MIN. In the case of an unsigned number, it just overflows to zero and starts over, while in the case of a signed integer, it rolls over to INT_MIN. In both cases this is referred to as integer overflow or integer wraparound.
You could put a band-aid on the solution by using long long int (likely 64-bits on most modern systems) instead of int for your primitive data type, or you could use a better approach like a library that supports (almost) arbitrarily long data types, like libBigInteger.
References
Integer Overflow, Accessed 2014-03-04, <http://en.wikipedia.org/wiki/Integer_overflow>
C++ Big Integer Library, Accessed 2014-03-04, <https://mattmccutchen.net/bigint/>
The limits.h Header File, Accessed 2014-03-04, <http://tigcc.ticalc.org/doc/limits.html>
This is my solution to calculating BIG fibonacci numbers
// Study for algorithm that counts n:th fibonacci number
#include <iostream>
#include <cstdlib>
#include "boost/multiprecision/cpp_int.hpp"
#define get_buffer(a) buffer[(a)%2]
#define BIG boost::multiprecision::cpp_int
int main(int argc, const char* argv[])
{
// atoi returns 0 if not integer
if(argc != 2 || atoi(argv[1]) < 1){
std::cout << "You must provide one argument. Integer > 0" << std::endl;
return EXIT_SUCCESS;
}
// ring buffer to store previous two fibonacci number, index it with [i%2]
// use defined function get_buffer(i), it will do the magic for you
BIG buffer[2]={ 1, 1 };
// n:th Fibonacci
unsigned int fn = atoi(argv[1]);
// count loop is used if seeked fibonacci number is gt 2
if(fn > 2){
for(unsigned int i = 2; i < fn; ++i){
get_buffer(i) = get_buffer(i-1) + get_buffer(i-2);
// get_buffer(i-1) + get_buffer(i-2) == buffer[0] + buffer[1]
// if you want to print out every result, do it here
}
}
// Result will be send to cout
std::cout << "Fibonacci[" << fn << "] is " << get_buffer(fn-1) << std::endl;
return EXIT_SUCCESS;
}