简体   繁体   中英

C++ Handling big numbers

Okay, I have to do simple task for my c++ class. Two functions, first is Fibonacci sequence, second some random sequence (finding e ). It looks like this:

#include <stdio.h>
#include <cstdlib>
#include <string>
#include <math.h>

void fib(int number)
{
    int a=0, b=1;
    printf("%d\n", a); 
    for (; number>0; number--)
    {
        printf("%d\n", b);
        b+=a;
        a = b-a;
    }
}

void e_math(unsigned int number)
{
    for (double n = 1; number>0; number--, n++)
    {
        printf("%f\n", pow((1+1/n), n));
    }
}

int main(int argc, char** argv)
{
    if (std::string(argv[2])=="f") fib(atoi(argv[1])-1);
    if (std::string(argv[2])=="c") e_math(atoi(argv[1])-1);
    else printf("Bad argument\n");
}

So at the end I did g++ main.cpp -o app;./app 10 f . It worked perfectly. But when I thought: Hmm, maybe lets check for bigger number, and added 50 it just messed up. I mean it did good for about 40 sequence numbers (checked with Python), but then it started to printf() negatives etc. I figured it's probably about int range. So I changed int a=0, b=1 to long long a=0, b=1 , but still it prints the same (I still use printf("%d..) , because %lld does not work

There are information in comments telling you how to be able to print long long correctly so that you can benefit from the whole range. However, as said blazs in his answer, you will not go much further (it will cycle for n=94 on unsigned 64 bits).

If you want to handle much bigger Fibonacci numbers (in fact, arbitrary large numbers) you can use boost::multiprecision .

For example:

#include <boost/multiprecision/gmp.hpp>  

boost::multiprecision::mpz_int fib(boost::multiprecision::mpz_int number)
{
    boost::multiprecision::mpz_int a=0, b=1;
    for (; number>0; number--)
    {
        b += a;
        a = b-a;
    }
    return a;
}

int main()
{
    std::cout << fib(500);
}

You'll need to link with gmp when building. For example:

g++ -o fib fib.cc -lgmp
./fib
139423224561697880139724382870407283950070256587697307264108962948325571622863290691557658876222521294125

The n th Fibonacci number is around 1.6^n which for n=50 is a big number (it's 53316291173 ). You may be able to represnet it as long , but as the thing grows exponentially, you won't be able to store Fn for large n into a primitive data type (where Fn denotes the n th Fibonacci number): the n+1 th Fibonacci number is roughly 1.6 times the n th Fibonacci number.

You need a big int data type to compute Fn for large n .

You can use Integer classes from The GNU Multiple Precision Arithmetic Library . Here the link to the C++ Interface .

Edit: Also look at 15.7.4 Fibonacci Numbers .

Since %lld is not portable and does not work in any compiler, what about if you declare a and b as long and print the result with c++ std::cout?

This is necessary since the 50th Fibonacci number is 7778742049, which is bigger than the typical max positive integer value (32 bits) that is 2147483647.

By the way, you should remove the last else , I don't think is doing what you want when the parameter f is provided.

Here is the code working.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM