Integer overflow in unsigned long long array - c++

I was trying to make cached Fibonacci sequence, but seem to be running into integer overflow (even if the data type is unsigned long long) after nth position = 247, the compiler outputs strange erroneous negative results, which I was not hoping for. Was wondering what a solution to this is, beyond n=247, and how I can increase accurate result up to essentially n= any positive integer if that possible... Thanks.
I was also trying to set the array capacity to the nthPos but it only accepts constant integers (not even constant variables!), was wondering what a way around this is...
#include <iostream>
#include <cstdlib>
#include <string>
#include <time.h>
#include <cmath>
using namespace std;
int FibonacciRecursiveFunc(int nthPos) {
unsigned long long firstNum = 0; unsigned long long secondNum = 1;
unsigned long long PastFibonacciCache[300] = { firstNum,secondNum };
if (find(PastFibonacciCache, end(PastFibonacciCache), nthPos-1) != end(PastFibonacciCache)) {
return nthPos - 1;
}
else {
for (int i = 2; i < nthPos; i++) {
PastFibonacciCache[i] = PastFibonacciCache[i - 1] + PastFibonacciCache[i - 2];
if (i > 300) {
unsigned long long SecondLastTerm = PastFibonacciCache[299];
unsigned long long lastTerm = PastFibonacciCache[300];
PastFibonacciCache[300] = {}; PastFibonacciCache[0] = SecondLastTerm; PastFibonacciCache[1] = lastTerm;
i - 300; nthPos - 300;
}
}
return PastFibonacciCache[nthPos%300-1];
}
}
int main() {
string inputVAL; int nthPos;
cout << "Greetings, enter a valid n value | n >= 1\n" << "type exit, quit or break to quit program \n\n" << endl << " ->";
getline(cin, inputVAL);
string exit_Methods[3] = { "exit", "quit", "break" };
while (find(exit_Methods, end(exit_Methods), inputVAL) == end(exit_Methods)) {
bool exception_caught = true;
try {
nthPos = stoi(inputVAL);
exception_caught = false;
}
catch (invalid_argument) {
cerr << "invalid argument" << endl;
}
catch (out_of_range) {
cerr << "number is too big" << endl;
}
catch (exception) {
cerr << "something went horribly wrong :v" << endl;
}
if (!exception_caught) {
//begintimer for calculation speed
time_t begin, end;
time(&begin);
if (nthPos >= 1) {
cout << FibonacciRecursiveFunc(nthPos) << endl;
}
else {
cout << "ERR" << endl;
}
// measure elapsed time
time(&end);
time_t elapsed = end - begin;
printf("Time measured: %ld seconds.\n\n", elapsed);
}
cout << "enter a valid n value | n >= 0 ->";
getline(cin, inputVAL);
}
}

int FibonacciRecursiveFunc(int nthPos) {
The return type of your function is int. The maximum value representable by int varies between systems, but let's assume that it is 2147483647 on your system.
The 247th fibonacci number is 1152058411884454788302593034206568772452674037325128. This number is greater than 2147483647. You cannot represent so large number with an int.
was wondering what a way around this is
You cannot use fundamental types. You can use arbitrary precision arithmetic.

Related

Returning multiple values using pointers in a function

Can anyone help me to understand how to return multiple values using pointers in a function? I am confused with the following example.
Can we assign other values to int value besides 0 or 1, while the program can still run normally?
What does defining the value of 0 and 1 in the if statement and else statement do for us in the int factor function?
What does if(!error) statement do in the main ()?
#include <iostream>
using namespace std;
int factor(int n, int *p_addition, int *p_subtraction, int *p_squared, int *p_cubed)
{
int value = 0;
if (n >= 0 && n <= 100)
{
*p_addition = n + n;
*p_subtraction = n - n;
*p_squared = n*n;
*p_cubed = n*n*n;
value = 0;
}
else
{
value = 1;
}
// This function will return a value of 0 or 1
return value;
}
int main()
{
int number, num_add, num_sub, squared, cubed;
int error;
cout << "Enter a number between 0 and 100: ";
cin >> number;
error = factor(number, &num_add, &num_sub, &squared, &cubed);
if (!error)
{
cout << "number: " << number << endl;
cout << "num_add: " << num_add << endl;
cout << "num_sub: " << num_sub << endl;
cout << "squared: " << squared << endl;
cout << "cubed: " << cubed << endl;
}
else
{
cout << "Error encountered!!" << endl;
}
return 0;
}
int is at least 16 bits (depending on the system - hardware, operating system, 32-bit computing / vs. 64-bit computing), for numeric range, cf: https://en.cppreference.com/w/cpp/language/types (at least -32768 to 32767 for 16 bit integers).
factor contains return value, which (here) signifies to the caller, whether an error occurred. It has no other effect within factor.
The ! negates the boolean value, so that the test is for false. if with an int implicitly converts to bool and tests for error being 0: https://en.cppreference.com/w/cpp/language/implicit_conversion#Boolean_conversions The value zero (for integral [...]) [...] become[s] false. All other values become true.
So any value beside 0 would have the same effect instead as 1.
It would have been better to name value something like wrong_input_range.
It would have been better to make value a bool type instead of int and make the return type of factor bool, too.
Whether your main returns a value beside 0 in case of the error, you can decide by yourself. Within a script, the returned value of called programs often is tested to know, whether the script can continue.

Unexpected behaviour of Priority_queue size

I was writing the code for the problem. Median of the stream of integers when I encountered an issue. Note that this issue is not the algorithmic but rather ambiguous behavior of the priority_queue size.
#include <bits/stdc++.h>
using namespace std;
priority_queue<double> small;
priority_queue<double, vector<double>, greater<double> > large;
void rebalance()
{
cout << "Initial size\n";
cout << "small " << small.size() << " large " << large.size() << endl;
if (small.size() - large.size()>1)
{
large.push(small.top());
small.pop();
}
else if (large.size() - small.size()>1)
{
cout << "Unexpectedly goes here\n";
cout << "garbage size difference " << large.size() - small.size() << endl;
small.push(large.top());
large.pop();
}
}
void addNum(int num) {
if (small.size() == 0 || num<small.top())
{
small.push(num);
}
else
{
large.push(num);
}
rebalance();
}
double findMedian() {
if (small.size() == large.size())
{
double ans = (small.top() + large.top()) / 2.0;
return ans;
}
else if (small.size()>large.size())
{
return (double)small.top();
}
else
{
return (double)large.top();
}
}
int main()
{
std::ios_base::sync_with_stdio(false);
int num = 5;
addNum(num);
cout << findMedian() << endl;
return 0;
}
The output for this code is
Initial size
small 1 large 0
Unexpectedly goes here
garbage size difference 18446744073709551615
fish: “./a.out” terminated by signal SIGSEGV (Address boundary error)
In the rebalance function the initial size of small is 1 and large is 0 which suggest that the loop should neither enter the if condition nor the else if condition but the loop enters the else if condition with a garbage value in size.why does this happen? Moreover I tried saving the small and large size in an integer variable and then comparing them in conditionals,which lead to acceptance of the code. Hence the algorithm handles the correctness.
What leads to this garbage value?
In
else if(large.size()-small.size()>1)
size() returns an unsigned number. A unsigned number can never be negative so if would be a negative number it wraps around to the largest number it could be and then goes backwards from there. Since large has a size of 0 and small has a size of 1 then 0 - 1 gives you 18446744073709551615. I believe what you are trying to do should be expressed as
if(small.size() < large.size())
{
small.push(large.top());
large.pop():
}
else if(large.size() < small.size())
{
large.push(small.top());
small.pop();
}

How do I generate any random number UNDER or ABOVE a certain number in C++?

For example, I'm making a guessing game. If the computer guesses too low, I want to send it to this function
int player1::guessLow(int g)
{
return rand() % guess + 1;
}
So that it guesses any number ABOVE what it just guessed. I also want to do the same for when it's too high
int player1::guessHigh(int g)
{
return rand() % guess - 1;
}
Obviously this isn't the correct code but how would I do this? The < and > operators don't work between in front of guess. I'm trying to come up with any random number and help the computer remember so it keeps guessing below or above that number. How would I accomplish this? Is there an algorithm or template that I can use?
UPDATE:
Here is the code
bool checkForWin(int guess, int answer)
{
cout << "You guessed " << guess << ". ";
if (answer == guess)
{
cout << "You're right! You win!" << endl;
return true;
}
else if (answer < guess)
cout << "Your guess is too high." << endl;
else
cout << "Your guess is too low." << endl;
return false;
}
void play(Player &player1, Player &player2)
{
int answer = 0, guess = 0;
answer = rand() % 100;
bool win = false;
while (!win)
{
cout << "Player 1's turn to guess." << endl;
guess = player1.getGuess();
win = checkForWin(guess, answer);
if (win) return;
cout << "Player 2's turn to guess." << endl;
guess = player2.getGuess();
win = checkForWin(guess, answer);
}
}
There are many examples of generating a random number in a given range using the standard C++ facilities. Here is a little thread-safe function to get you a number in a range:
#include <chrono>
#include <iostream>
#include <random>
long random( long min, long max )
{
// Create and initialize our PRNG
thread_local auto seed = std::chrono::system_clock::now().time_since_epoch().count();
thread_local std::ranlux48 prng( seed );
return std::uniform_int_distribution <long> ( min, max )( prng );
}
(If you are only single-threaded, you can replace thread_local with static.)
To get a range only bounded by minimum or maximum, use numeric_limits<> to find the lowest/highest value to bound with:
#include <limits>
int main()
{
std::cout << "Maximum value of 12: " << random( std::numeric_limits <long> ::min(), 12 ) << "\n";
}
Hope this helps.
rand() is part of C++ (at least for now) and is fine for a simple guessing game.
In some cases srand may not be appropriate, for example I might want repetitive behavior and predictability for testing purposes.
For this problem you may wish to use srand otherwise the guessing game gets boring.
You should completely avoid rand in many applications such as cryptography.
But here the issue is more basic. You don't need to keep track of all the numbers which you have guessed. You just have to keep track of minimum and maximum range. Example:
#include <iostream>
#include <ctime>
#include <cstdlib>
using std::cout;
int main()
{
srand((unsigned int)time(NULL));
int guess = rand();
int min = 0;
int max = RAND_MAX;
while(true)
{
int n = min + rand() % (max - min);
//(n goes up to max, not including max)
if(n < guess)
{
min = n + 1;
cout << n << " too low\n";
}
else if (n > guess)
{
max = n;
cout << n << " too high\n";
}
if(min == max)
n = min;
if(n == guess)
{
cout << n << " success\n";
break;
}
}
return 0;
}
Or use this function as suggested in comment, to find a number within a range.
int rand_rang(int min, int max)
{
if(min == max)
return min;
return min + (int)((double)rand() / ((double)RAND_MAX + 1) * (max - min));
}
These are all pseudo random numbers. If you are designing this game for a lottery corporation, then use a secure random number generator which is more difficult to crack. If distribution is very important (physics simulation etc.) then again you want to avoid rand

Reading into an Array Multiple Times

I'm having a little trouble with my code. It's pretty much supposed to open two files, and compare the first twenty line of the file "StudentAnswers.txt" [inputted as a char into a char array] against a char value in (each line of another file) "CorrectAnswers.txt" in another array at the same position (index). It's like a linear search, but the same position in the arrays. Then a report should be displayed, detailing which question the student missed, the given answer, the correct answer, and if the student passed (got >= 70%) or not, like the following:
Report for Student X:
2 (A/D), 3 (C/D), 5(D/A)
This student passed the exam!
Then it should clear the SAArray, and feed the next twenty lines from StudentAnswers.txt, and start the process all over again. I guess the program has to determine the number of students from (lines of 'StudentAnswers.txt' file / 20).
I'm having trouble displaying the report, and having the array clear itself after the program. I'm guessing this can be done with a while loop and an accumulator for the number of students (to be determined by above equation).
Also, Visual Studio seems to go to "Missed __ questions for a total of ___ %", and then keep looping -858993460.
Any help would be appreciated.
#include <iostream>
#include <fstream>
#include <string>
#include <array>
#include <algorithm>
using namespace std;
void GradeReturn(char[], char[], int, int, int);
string PassFail(float);
int main()
{
ifstream SA("StudentAnswers.txt");
ifstream CA("CorrectAnswers.txt");char CAArray[20];
char SAArray[20];
// char SA2Array[20];
bool isCorrect;
int correct;
int incorrect;
int counter;
correct = 0;incorrect = 0;
counter = 0;
cout << endl;
if (!SA.fail())
{
cout << "'StudentAnswers.txt' file opened successfully." << endl;
cout << "'CorrectAnswers.txt' file opened successfully." << endl << endl;
int a = 0;
int b = 0;
while (a < 20)
{
CA >> CAArray[a];
a++;
} // while loop to feed char into the array
while (b < 20)
{
SA >> SAArray[b];
b++;
}
} // while loop to feed char into array
CA.close(); // closing "CorrectAnswers.txt"
SA.close(); // closing "StudentAnswers.txt"
GradeReturn(&CAArray[counter], &SAArray[counter], correct, incorrect, counter);
return 0;
}
void GradeReturn(char CAArray[], char SAArray[], int correct, int incorrect, int counter)
{
float percent;
float hundred;
int student;
int catcher[20];
int writeCatcher; int starter;
int catcher_size;
student = 0;
writeCatcher = 0;
catcher_size = ((sizeof catcher) / 4);
while (counter < 20)
{
if ((CAArray[counter]) == (SAArray[counter]))
{
correct++;
cout << "Good job!" << endl;
} // correct handling
else
{
incorrect++;
cout << "You got question " << counter << " wrong." << endl;
counter >> catcher[writeCatcher];
writeCatcher++;
} // incorrect handling
counter++;
} // while loop to determine if a student got a question right or wrong
static_cast <float> (incorrect); // float conversion
cout << endl; // for cleanliness
percent = ((static_cast <float> (correct)) / 20); // percentage
hundred = percent * 100;
PassFail(percent);
if (PassFail(percent) == "pass")
{
student++;
cout << "Report for Student " << student << ":" << endl;
cout << "-----------------------------" << endl;
cout << "Missed " << incorrect << " questions out of 20 for ";
cout << hundred << " % correct." << endl << endl;
starter = 0;
while (starter < (sizeof catcher)
{
if(1=1)
{
catcher_size
}
else
{
cout << "";
starter++;
}
}
}
else if (PassFail(percent) == "fail")
{
student++;
cout << "Missed " << incorrect << " questions out of 20 for ";
cout << hundred << " % correct." << endl << endl;
while (starter < catcher_size)
{
if ((catcher[starter]) == -858993460)
{
starter++;
}
else
{
cout << "";
starter++;
}
}
}
return;
}
string PassFail(float percent)
{
if (percent >= 0.70) // if <pass>
{
return "pass";
}
else // if <fail>
{
return "fail";
}
cout << endl;
}
To get a loop you should keep streams open instead of closing them after reading 20 lines.
As pseudo code that would be:
a = 0;
while(streams_not_empty)
{
CA >> CAArray[a];
SA >> SAArray[a];
++a;
if (a == 20)
{
GradeReturn(&CAArray[counter], &SAArray[counter], correct, incorrect, counter);
a = 0; // Reset a
}
}
CA.close(); // closing "CorrectAnswers.txt"
SA.close(); // closing "StudentAnswers.txt"
You would also need to pass correct, incorrect, counter by reference so that the GradeReturn can change their value and their by do the accumulation.
Like:
void GradeReturn(char CAArray[], char SAArray[], int& correct, int& incorrect, int& counter)
Further you shouldn't rely on being able to read exactly Nx20 lines from the files every time. A file could have, e.g. 108 (5x20 + 8) lines, so you code should be able to handle the with only 8 lines. In other words, don't hard code 20 in your function like while (counter < 20). Instead pass the number of lines to be handled and do while (counter < number_to_handle).
Something like this as pseudo code:
a = 0;
while(streams_not_empty)
{
CA >> CAArray[a];
SA >> SAArray[a];
++a;
if (a == 20)
{
GradeReturn(&CAArray[counter], &SAArray[counter], correct, incorrect, counter, a);
// ^
a = 0; // Reset a
}
}
if (a != 0)
{
// Process the rest
GradeReturn(&CAArray[counter], &SAArray[counter], correct, incorrect, counter, a);
}
CA.close(); // closing "CorrectAnswers.txt"
SA.close(); // closing "StudentAnswers.txt"
One problem you have is you're trying to compare C-style strings with the == operator. This will compare them essentially as if they were pointers to char, i.e. compare whether they point at the same location in memory, not compare the contents of the string. I urge you to look up array-decay and c-string variables to understand more.
Specifically, if (PassFail(percent) == "pass") isn't going to do what you want it to. strcomp doc, strncmp doc using std::string variables instead of c-style strings would all work, but it would be better simply to compare percent to a value, i.e. if(percent >= 0.70 directly instead of calling PassFail and comparing a string.
There are many other issues here also, you at one point call PassFail but do nothing with the return value. The only side affect of PassFail is cout << endl, if that's what you intend, it's a poor decision and hard to read way to put a newline on the console.
Try asking your compiler for more warnings, that's often helpful in finding these types of issues. -Wall -Wextra work for gcc, you may have to read your compiler manual...

Increment double by smallest possible valueTest

I want to increment a double value from the smallest possible (negative) value it can take to the largest possible value it can take.
I've started off with this:
int main()
{
double min(numeric_limits<double>::min());
double i(min);
while(i < 0);
{
cout << i << endl;
i += min ;
}
}
Unfortunately, this doesn't produce the desired result - the while loop is skipped after one iteration.
Is there a better way to accomplish my goal?
I'm guessing at what you want from your code: You want to start with largest possible negative value and increment it toward positive infinity in the smallest possible steps until the value is no longer negative.
I think the function you want is nextafter().
int main() {
double value(-std::numeric_limits<double>::max());
while(value < 0) {
std::cout << value << '\n';
value = std::nextafter(value,std::numeric_limits<double>::infinity());
}
}
Firstly,
while(i < 0); // <--- remove this semicolon
{
cout << i << endl;
i += min ;
}
Then, std::numeric_limits<double>::min() is a positive value, so i < 0 will never be true. If you need the most negative value, you'll need
double min = -std::numeric_limits<double>::max();
but I don't know what your i += min line is supposed to do. Adding two most negative number will just yield −∞, and the loop will never finish. If you want to add a number, you'll need another variable, like
double most_negative = -std::numeric_limits<double>::max();
double most_positive = std::numeric_limits<double>::max();
double i = most_negative;
while (i < 0)
{
std::cout << i << std::endl;
i += most_positive;
}
Of course this will just print the most negative number (-1.8e+308), and then i becomes 0 and the loop will exit.
The following runs through all float-values 'in order'. The steps between successive values become smaller as u.mind increases.
No guarantee this is correct and it will take a long time to complete and this isn't portable and it will take even longer for doubles and... etc. etc.
#include <cassert>
#include <iostream>
#include <limits>
union umin {
float mind;
int mini;
} u;
int main()
{
u.mind = std::numeric_limits<float>::max();
std::cout << -u.mind << " " << u.mini << std::endl;
while ( u.mind > 0 ) {
float previous = u.mind;
u.mini -= 1;
std::cout << -u.mind << " " << u.mini << " " << previous - u.mind << std::endl;
assert( previous > u.mind );
}
}