C++ Handling big numbers

安稳与你 提交于 2021-02-07 20:27:13

问题


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


回答1:


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



回答2:


The nth 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 nth Fibonacci number): the n+1th Fibonacci number is roughly 1.6 times the nth Fibonacci number.

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




回答3:


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.




回答4:


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.



来源:https://stackoverflow.com/questions/35814019/c-handling-big-numbers

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!