long long variable becomes negative after I surpass 9-11 digits (C++) - c++

FIXED: The function that recieved the num variable and printed it on the calculator screen, recieved an "int" parameter
I'm a beginner and trying to make a calculator on console. You have to type each number just like in real calculators and they appear on the left.
This is the function to get digits of the next input so I know how many 0's I have to run.
int getDigits(int number)
{
int getDigits = 0;
while (number) {
number /= 10;
getDigits++;
}
return getDigits;
}
UPDATED GETDIGIT FUNCTION
long long getDigits(long long number)
{
long long getDigits = 0; //i know long long wasn't needed here
while (number) {
number /= 10;
getDigits++;
}
return getDigits;
}
The main number displaying on the calculator screen is a long long "num" and it changes every do while iteration.
case 1:
long long aux, aux2;
cout << "Number: "; cin >> aux;
aux2 = pow(10, getDigits(aux));
num *= aux2;
num += aux;
break;
This just takes the second input places it on the right. It works perfectly but
in this case when "num" excel 11 variables, it just becomes a negative number (i have no idea why, i did the operations manually and it should work fine). For example:
input: 1
num = 1
input: 2
num = 12
but when it reaches 11 digits
num = 12345678911
input = 1
num = -538112777 (instead of the 123456789111)
Why is this? all my variables are long long and should be enough, help really appreciated.

Integers in C++ have limited capacity. Going beyond the capacity or range results in an overflow.
An overflow could wrap around and become negative. The platform could generate an overflow exception.

Looking closely on your code, firstly
{
int getDigits(int number)
{
int getDigits = 0;
while (number) {
number /= 10;
getDigits++;
}
return getDigits;
}
You are passing getDigits(long long aux) to getDigit function thats is wrong.
Futhermore : why value become negative: the 8 bits are used to store character in which the RMB thats 8th from right to left and 1st from left to right when the value exceed binary 127 the right most bit is set which makes the value negative. The same happens to all the datatypes that are signed

FIXED: The function that recieved the num variable and printed it on the calculator screen, recieved an "int" parameter

Related

detecting 32 bit integer overflow

I have a simple method that basically reverses the signed integer. This function works till the integer is under or equal to 32 bit.
for example :-
input = 321
output = 123
input = -321
output = -123
input = 1534236469
output = 9646324351 //this value is wrong.
expected output = 0
I want to detect the integer overflow and return 0 in that case.
Below is the code for the function
int reverse(int x) {
int number = x;
bool negative = false;
if(number<0){
negative = true;
number *= -1;
}
int reversed = 0;
while (number != 0){
int reminder = number % 10;
reversed = (reversed * 10) + reminder;
number /= 10;
}
if(negative){
reversed *= -1;
}
return reversed;
}
Furthermore, if I change the input and output into signed long I get the required output but I want to detect the integer overflow and return 0.
Before you multiply reversed by 10, just check to make sure it's small enough to multiply by 10.
Similarly, before you add remainder, check to make sure it's small enough to add remainder.
There's a clever trick you can use for the addition, but at your level you probably shouldn't:
if ((reversed += remainder) < remainder) {
//overflow
}
Note that the trick only works if both reversed and remainder are unsigned.
This hint might help you complete your assignment:
You are only going to get integer overflow if your final number is 10 digits long and the first digit ends up being above or equal to 2.
Which means that you are going to get integer overflow if your original number is also 10 digits long and the last digit is 2 or above.

Counting number of digits in a double C++

I'm using a while loop to count the number of digits in my input.
So my input was 1.525
length = 0;
num = num - int(num);
while ( num >= .0001 ) {
num = num * 10;
length = length + 1;
num = num - int(num); }
When i do
cout << "\n\nLength: " << length << "\n";
The answer I get is 51 and other numbers give me an asnwear of 49 or something that is obviously wrong.
Is it the way c++ works or is it just my mistake. Thank you.
double and float can't always hold precisely the values you try to store in them, thats not how they work. In many cases they will store an approximate value, that usually can be rounded up to what you meant to store there in the first place, but not exactly. Thats why you are getting those results.
You can use string or char array to store the the number inputed. it can precisely count the length. float double store a approximate value, you can reference here.
Floating point numbers cannot store the decimal 1.525 precisely but if you use round instead of int cast and use fabs when comparing against the tolerance to protect against negative numbers you will get something you might be happy with:
num -= round(num);
while(fabs(num) >= .0001) {
num *= 10;
++length;
num -= round(num);
}
If you are happy to accept that 1.9999999 has the same number of digits as 2.0.
Generally, trying to find the number of digits in a floating point number is going to be a bit meaningless because it is not stored as decimal digits.

Issue with pow and round - answers are not equivalent

I'm having an issue creating a function that checks if a root can be simplified. In this example, I'm trying to simplify the cube root of 108, and the first number that this should work for is 27.
In order to do this, I am calling pow() with the number being the index (in this case, 27), and the power being (1/power), which in this instance is 3. I then compare that to the rounded answer of pow(index,(1/power)), which should also be 3.
Included is a picture of my problem, but basically, I am getting two answers that are equivalent to 3, yet my program is not recognizing them as equal. It seems to be working elsewhere in my program, but will not work here. Any suggestions as to why?
int inside = insideVal;
int currentIndex = index;
int coeff = co;
double insideDbl = pow(index, (1/(double)power));
double indexDbl = round(pow(index,(1/(double)power)));
cout<<insideDbl<< " " << indexDbl <<endl;
//double newPow = (1/(double)power);
vector<int> storedInts = storeNum;
if(insideDbl == indexDbl){
if(inside % currentIndex == 0){
storedInts.push_back(currentIndex);
return rootNumerator(inside/currentIndex, currentIndex, coeff, power, storedInts);
}
else{
return rootNumerator(inside, currentIndex + 1, coeff, power, storedInts);
}
}
else if(currentIndex < inside){
return rootNumerator(inside, currentIndex + 1, coeff, power, storedInts);
}
I tried to add a picture, but my reputation apparently wasn't high enough. In my console, I am getting "3 3" for the line that reads cout<<insideDbl<< " " << indexDbl <<endl;
EDIT:
Alright, so if the answers aren't exact, why does the same type of code work elsewhere in my program? Taking the 4th Root of 16 (which should equal 2) works using this segment of code:
else if( pow(initialNumber, (1/initialPower)) == round(pow(initialNumber,(1/initialPower)))){
int simplifiedNum = pow(initialNumber, (1/initialPower));
cout<<simplifiedNum;
Value* simplifiedVal = new RationalNumber(simplifiedNum);
return simplifiedVal;
}
despite the fact that the conditions are exactly the same as the ones that I'm having trouble with.
Well you are a victim of finite precision floating point arithmetic.
What happened?
This if(insideDbl == indexDbl), is very dangerous and misleading. It is in fact a question whether (Note: I made up the exact numbers but I can give you precise ones) 3.00000000000001255 is the same as 2.999999999999996234. I put 14 0s and 14 9s. So technically the difference goes beyond 15 most significant places. This is important.
Now if you write insideDbl == indexDbl, the compiler compares the binary representantions of them. Which are clearly different. However, when you simply print them, the default precision is like 5 or 6 significant digits, so they get rounded, and seem to be the same.
How to check it?
Try printing them with:
typedef std::numeric_limits< double > dbl_limits;
cout.precision(dbl::max_digits10);
cout << "Does " << insideDbl << " == " << indexDbl << "?\n";
This will set the precision, to the number of digits, the are necessary to differentiate two numbers. Please note that this is higher than the guaranteed precision of computation! That is the root of confusion.
I would also encourage reading numeric_limits. Especially about digits10, and max_digits10.
Why sometimes it works?
Because sometimes two algorithms will end up using the same binary representation for the final results, and sometimes they won't.
Also 2 can be a special case, as I believe it can be actually represented exactly in binary form. I think (but won't put my head on it.) all powers of 2 (and their sums) can be, like 0,675 = 0,5+0,125 = 2^-1 + 2^-3. But please don't take it for granted unless someone else confirms it.
What can you do?
Stick to the precise computations. Using integers, or whatever. Or you could assume that everything 3.0 +/- 10^-10 is actually 3.0 (epsilon comparisons), which is very risky, to say the least, when you do care about precise math.
Tl;dr: You can never compare two floats or doubles for equality, even when mathematically you can prove the mentioned equality, because of the finite precision of computations. That is, unless you are actually interested in the same binary representation of the value, as opposed to the value itself. Sometimes this is the case.
I suspect that you'll do better by computing the prime factorisation of insideVal and taking the product of those primes that appear in a multiple of the root.
For example
108 = 22 × 33
and hence
3√108 = 3 × 3√22
and
324 = 22 × 34
and hence
3√324 = 3 × 3√(22 × 3)
You can use trial division to construct the factorisation.
Edit A C++ implementation
First we need an integer overload for pow
unsigned long
pow(unsigned long x, unsigned long n)
{
unsigned long p = 1;
while(n!=0)
{
if(n%2!=0) p *= x;
n /= 2;
x *= x;
}
return p;
}
Note that this is simply the peasant algorithm applied to powers.
Next we need to compute the prime numbers in sequence
unsigned long
next_prime(const std::vector<unsigned long> &primes)
{
if(primes.empty()) return 2;
unsigned long p = primes.back();
unsigned long i;
do
{
++p;
i = 0;
while(i!=primes.size() && primes[i]*primes[i]<=p && p%primes[i]!=0) ++i;
}
while(i!=primes.size() && primes[i]*primes[i]<=p);
return p;
}
Note that primes is expected to contain all of the prime numbers less than the one we're trying to find and that we can quit checking once we reach a prime greater than the square root of the candidate p since that could not possibly be a factor.
Using these functions, we can calculate the factor that we can take outside the root with
unsigned long
factor(unsigned long x, unsigned long n)
{
unsigned long f = 1;
std::vector<unsigned long> primes;
unsigned long p = next_prime(primes);
while(pow(p, n)<=x)
{
unsigned long i = 0;
while(x%p==0)
{
++i;
x /= p;
}
f *= pow(p, (i/n));
primes.push_back(p);
p = next_prime(primes);
}
return f;
}
Applying this to your example
std::cout << factor(108, 3) << std::endl; //output: 3
gives the expected result. For another example, try
std::cout << factor(3333960000UL, 4) << std::endl; //output: 30
which you can confirm is correct by noting that
3333960000 = 304 × 4116
and checking that 4116 doesn't have any factor that is a power of 4.

Weird output as the numbers get bigger in Fibonacci sequence

I noticed in my fibonacci sequence that I'm getting negative numbers after a certain point:
267914296 433494437 701408733 1134903170
1836311903 -1323752223 512559680 -811192543 -298632863
Does this have to do with the limited range of "int"? or is there something wrong with my code?
Here is the code:
using std::cout;
int main()
{
int n = 50, f1 = 0, f2 = 1, fn = 0, i = 0;
cout << "0 ";
for (i = 0; i < n; i++)
{
fn = f1 + f2;
f2 = f1;
f1 = fn;
cout << fn << " ";
}
Yes, this has to do with the limited range of int. This is called rollover or overflow, and works just like the odometer in your car. Once the number passes its highest possible value, it rolls over to its lowest possible value (which for int is a negative number). Consider using an unsigned int or long unsigned int, though the second one is not neccessarily longer (it's platform-dependent). A long double can hold even bigger numbers. If you'd like to use an arbitrarily large number (as big as you want), you can find appropriate libraries in answers to this question.
I'll bet it does have something to do with the range of int. you're probably overflowing
An integer normally has 32 bits, and one of those bits is the sign, so if you have a number like
01111111111111111111111111111111
which is a little bit over 2 billion, and you add 2 to it, then you get
10000000000000000000000000000001
which is negative(the first number is the sign, 0 is positive and 1 is negative)
If you want to store more numbers, you can use long ints.
Try using "long int" instead of "int".

Number changing value when assigned to variable?

I have a little problem when assigning a result to a variable, this is happening the first time to me now. I call Convert() with "aaa" as a parameter, here is my output:
aaa
**676** *(value from cout)* = 26^(3-1)*1 **675** *(value of the variable)*
+26 = 26^(3-2)*1 700
+1 = 26^(3-3)*1 701
701
And here the code:
string alphabet="abcdefghijklmnopqrstuvwxyz";
unsigned long long Convert(string &str){
unsigned long long wvalue=0;
for(int i=0;i<str.size();++i){
size_t found=alphabet.find(str[i]);
if(found==string::npos)
cout<<"Please enter only lowercase letters of the english alphabet!"<<endl;
unsigned long long add=((found+1)*pow(26,(str.size()-(i+1))));
wvalue+=add;
if(i>0)cout<<"+";
cout<<"\t"<<((found+1)*pow(26,(str.size()-(i+1))))<<" = "<<"26^("<<str.size()<<"-"<<(i+1) <<")*"<<(found+1)<<"\t"<<wvalue<<endl;
}
return wvalue;
}
Chances are I'm missing something awfully obvious, but I cannot figure it out.
((found+1)*pow(26,(str.size()-(i+1))))
is doing the calculation, and it is doing as it is supposed to, the result within the cout-statment is correct. But the variable is substracted by 1 in the first two assignments.
pow is a floating-point function. It takes and returns floating point numbers. Assigning a floating-point number to an integer variable truncates it to an integer number, so it might have been 675.9999999 just before the assignment, which will turn into 675 when assigned to the integer variable add.
cout also rounds floating-point numbers, depending on the configuration for example to 6 significant digits. 676.0 is a better approximation than 675.999, so you see 676 in the output.
Since you don't want to calculate with real numbers but only with integral numbers, you better stay with integral functions. To take 26 to the power of n, better use multiplication n times. Since you already use a loop, and like to have the next power of 26 for every character, the best is to add a variable in which you keep the current power value, like this:
unsigned long long currentFactor = 1;
for (...) {
...
unsigned long long add = currentFactor * (found+1);
wvalue += add;
currentFactor *= 26;
}
Also note that you don't have to find the character in an alphabet string. You can also just use character arithmetic to do this:
int charNumber(char c) {
if (c >= 'a' && c <= 'z')
return c - 'a'; // calculate the position of c relative to 'a'
else
return -1; // error
}