problem of scale?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
int main()
{
    long long user_number, sum=0, working, power;

    //gets base number
    cout<<"Enter a number."<<endl;
    cin>>user_number;

    //gets exponent
    cout<<endl<<"Enter an exponent for this number."<<endl;
    cin>>power;

    //working is user_number^power
    working=pow(user_number,power);

    //working displays correctly for smaller numbers (I went as high as 10^10)
    //but then starts displaying weird, large, negative numbers
    cout<<user_number<<"^"<<power<<" = "<<working<<endl;

    while (working>0)
    {
        sum=(sum+(working%10));
        working=working-(working%10);
        working=working/10;
    }

    //when I output my number this way (instead of as "working"), it displays
    //correctly, but the digits still don't add up when the number gets too big
    cout<<"The sum of the digits of "<<pow(user_number,power)<<" is "<<sum<<"."<<endl;

    cin.sync();
    cin.get();
    return(0);
}


Any ideas as to what I could change to make this work for 2^1000? It works for more reasonable numbers: 5^3, 10^10, 13^10, but not, apparently for this large of a number. I tried using floats instead of ints, but then it wouldn't let me do the modulo operation.

I'm stumped again.

-Vince

PS Anyone know of a really good tutorial on variable types? I'm looking for a discussion of the pros/cons/limits of the variable types, how they behave, how to work with them, how they interact with each other, how to convert from one to another, and so forth. I'm not overly impressed with the one here on CPP.com. Thanks again.
Last edited on
What you are experiencing is arithmetic overflow.

You are using a long long to compute some number. If the result however is larger than what a long long can hold then it overflows and what you get is a negative number. This is perfectly reasonable.

You could alleviate some of your problems by using an unsigned long, however this is not theoretical math. Computers have limits, hard, physical limits. Therefore regardless of what kind of primitive type you use there will be a number which will also cause overflow.

In order to solve this you may wanna take a look into libraries such as http://gmplib.org/

For example. And this tutorial is the first thing I read about C++. I think it's one of the best out there :)
I think pow takes float types (float, double, or long double).
Long double must have a biggest max value than long long, but as you store back the result of pow in a long long, you are limited by long long size. Try declaring working as long double maybe
see: http://gmplib.org/

About a tutorial, I don't know one and I don't see why you would need it. There isn't that much to say..
The limits are given. Floating point types( float, double, etc. ) are imprecise. Integer types( int, long, short, char, etc. ) are precise. Integers wrap (if you try to store 257 in an unsigned char, 1 is stored), floats don't.
The type returned by a op b (there a and b are values and op is an operator +-*/) is the type of the bigger one. If at least one of them is a floating point type, the result is floating point too.
Conversions can be done implicitly.
What else?
Anyone ever take a look at GMP? I downloaded and tried to install once, and it was a nightmare. If anyone knows an easy way to install, please let me know. I'm using code::blocks 10.5, though I also have visual c++ 2010 express.
Topic archived. No new replies allowed.