Skip to main content
GameDev.net gamedev.net
🔒 Locked

Large Integers

Started by kubapl Oct 1, 2009 at 10:08 PM 33 replies 5.7k views
Original Post
kubapl
kubapl
Hi, I am trying to do calculations to numbers that are to big for int or even __int64. I have just installed boost and configured it with my visual studio. I'm using C++ and spent the last hour trying to find a code snippet showing how to use boost's integers to store large numbers with no luck. Thanks
Zahlman
Zahlman
Quote:
Original post by kubapl
Hi, I am trying to do calculations to numbers that are to big for int or even __int64. I have just installed boost and configured it with my visual studio. I'm using C++ and spent the last hour trying to find a code snippet showing how to use boost's integers to store large numbers with no luck.


Boost::integer is not meant for this purpose. Where did you get the idea that it was?
kubapl
kubapl
Oh a friend of mine suggested to try boost.

I'm taking a look at the GMP how do I install it? Am I suppose to just dump the files somewhere after I unzip them?
oler1s
oler1s
Third party libraries have instructions. Places to look include the website and links to documentation, the downloaded files, and a folder of documentation, a README and INSTALL file in the downloaded files, and so on.
kubapl
kubapl
The readme is useless as it only talks about the changes in the new version. As far as the installer its unrecognizable... I'm starting to think that I have a linux version ? Is there a .exe out there for vs 2008 pro?
kenshee
kenshee
Try string conversions.
SiCrane
SiCrane
Depending on what you're trying to do, you might find it easier just using a programming language with built-in big number support like Python.
Sneftel
Sneftel
Quote:
Original post by kubapl
The readme is useless as it only talks about the changes in the new version. As far as the installer its unrecognizable... I'm starting to think that I have a linux version ? Is there a .exe out there for vs 2008 pro?

If you google for a windows version, a few results come up, though they look like they might be outdated.
Erik Rufelt
Erik Rufelt
If you can compile for x64 you have __int128, if that is big enough.
oler1s
oler1s
Ah yes, Windows support. Look into MPIR, which forked from GMP and is Windows friendly.

Actually, MPIR is mentioned on the GMP website. You just have to read...
shultays
shultays
if you have time you can write your own one, it is not that hard

imagine big numbers as character arrays, each byte is one digit and you are working on at base 256 :D

like 0x1234 consist of two bytes and it is {0x12, 0x34}

for aritmetic operations it is same method as you do with pen and paper

to add two numbers like 0x1204 0x65FF

12 04
65 FF

sum of 04 and FF is 0x103 so you will write 03 to the result byte and 01 is remainder for next bytes

12 + 65 = 77 and plus one remainder from previous operation 78

result is 78 03

subtraction is same as previous one but this time remainder is either 0 or -1

multiplication is a bit harder, again you use a method similiar to pen and paper multiplication

but I have no idea how you can do division =D you can subtract one element from each other until you go negative and count number of subtraction but it won't be an efficent one.


here is an example program, I always wanted to write something like that that thanks for the oppurtunity :D

[sourcecode]#include <stdio.h>#include <stdlib.h>#include <string.h>#define size 20class LargeNum{  public:  unsigned char data[size];    void add(LargeNum &a){    int remaining = 0;    for(int i=0; i<size; i++){      remaining += data + a.data;      data = remaining&0xff;      remaining >>= 8;    }  }    void sub(LargeNum &a){    int remaining = 0;    for(int i=0; i<size; i++){      remaining += data - a.data;      data = remaining&0xff;      remaining >>= 8;    }  }      void mul(LargeNum &a){    unsigned char temp[size];      for(int i=0; i<size; i++) temp = 0;        for(int i=0; i<size; i++){      unsigned int remaining = 0;      for(int j=0; j<size-i; j++){        remaining += ((int)data[j])*(int)a.data + temp[i+j];        temp[i+j] = remaining&0xff;        remaining >>= 8;      }    }        for(int i=0; i<size; i++) data = temp;      }  void print(){    int i;        for(i=size-1; i>0; i--)      if(data) break;        printf("0x%x",data);    i--;    for(;i>=0; i--)      printf("%02x", data);    printf("\n");  }    LargeNum(char *str){                    char temp[size*2] = {0};    for(int i=0; i<size*2; i++) temp= '0';        int l = strlen(str);    for(int i=0; i<l; i++){      temp[size*2-l+i] = str;    }    for(int i=0; i<size; i++){      int n = temp[size*2-1-2*i];      int m = temp[size*2-2-2*i];      if(n >= '0' && n <= '9') n -= '0';      else if(n >= 'a' && n <= 'f') n -= 'a'-10;      else if(n >= 'A' && n <= 'F') n -= 'A'-10;            if(m >= '0' && m <= '9') m -= '0';      else if(m >= 'a' && m <= 'f') m -= 'a'-10;      else if(m >= 'A' && m <= 'F') m -= 'A'-10;                  data = n + 16*m;          }  }  };     int main(void){    LargeNum a("1234");    LargeNum b("4321");    LargeNum c("4000000000000");    LargeNum d("1");        a.print();    printf("+\n");    b.print();    printf("=\n");    a.add(b);    a.print();            printf("\n*\n");    c.print();    a.mul(c);    printf("=\n");    a.print();            printf("\n-\n");    d.print();    a.sub(d);    a.print();    }[/sourcecode]
taytay
SiCrane
SiCrane
Quote:
Original post by shultays
if you have time you can write your own one, it is not that hard

If it's not that hard then why doesn't your class handle division and think that one minus ten happens to be 0xfffffffffffffffffffffffffffffffffffffff1?
shultays
shultays
Quote:
Original post by SiCrane
Quote:
Original post by shultays
if you have time you can write your own one, it is not that hard

If it's not that hard then why doesn't your class handle division and think that one minus ten happens to be 0xfffffffffffffffffffffffffffffffffffffff1?


Because I wrote it in like ~1.5 hours to just give an idea to OP? It does not mean to do everything.

0x1 - 0x10 = -15 in base ten. which is equal to ...ffffff1 in hexadecimal if you use twos complement

Maybe not that easy but It won't take more than 3-4 days of programming. And I think it is a pretty good exercise for people interested in this topic, maybe it helps other people even if OP does not want it
taytay
SiCrane
SiCrane
Quote:
Original post by shultays
Maybe not that easy but It won't take more than 3-4 days of programming.

Prove it.
Erik Rufelt
Erik Rufelt
I posted earlier in the thread that you can use __int128, but it seems I was wrong, since I can't use it in VC++ 2008 even on x64 builds. Perhaps it's only available on Itanium or something, cause I get a 'not supported on this architecture' error.
s_p_oneil
s_p_oneil
SiCrane - shultays is being helpful, and IMO your comments and attitude are uncalled for.

shultays - If you're interested, you can improve your class a good bit without a lot of effort by adding shift left and right functions. You can then implement a more efficient multiply using shift and add, as well as a fairly efficient division using shift and subtract. If you Google "shift and subtract division", you'll see it's not that bad, and shouldn't take you more than an hour or two once you figure it out.

kubapl - If you just want a quick solution to a specific problem and you're willing to try a scripting language like Python or Ruby, SiCrane's advice could make your life about a hundred times easier. However, if your goal is to master C++, follow everyone else's advice. Figuring out how to deal with third-party libraries will teach you some things, and learning how to implement your own math classes will teach you other things. If you really want to master C++, I recommend you do both. Create a new class based on shultay's, then link in a library like MP and run some performance comparisons between the two.
SiCrane
SiCrane
Quote:
Original post by s_p_oneil
SiCrane - shultays is being helpful, and IMO your comments and attitude are uncalled for.

It is not helpful to tell someone in For Beginners to reinvent the wheel and then say that reinventing said wheel is significantly easier than it actually is. Misleading someone in For Beginners is actually the exact opposite of helpful.
shultays
shultays
Quote:
Original post by s_p_oneil
SiCrane - shultays is being helpful, and IMO your comments and attitude are uncalled for.

shultays - If you're interested, you can improve your class a good bit without a lot of effort by adding shift left and right functions. You can then implement a more efficient multiply using shift and add, as well as a fairly efficient division using shift and subtract. If you Google "shift and subtract division", you'll see it's not that bad, and shouldn't take you more than an hour or two once you figure it out.

kubapl - If you just want a quick solution to a specific problem and you're willing to try a scripting language like Python or Ruby, SiCrane's advice could make your life about a hundred times easier. However, if your goal is to master C++, follow everyone else's advice. Figuring out how to deal with third-party libraries will teach you some things, and learning how to implement your own math classes will teach you other things. If you really want to master C++, I recommend you do both. Create a new class based on shultay's, then link in a library like MP and run some performance comparisons between the two.


thank you, i wrote something like that.

here is the result. it is still far from perfect, still can be optimized greatly but I am too tired for now.

it can do + - / * % operations and can work on both positive and negative numbers also can do shifting operations. and you can do comparisons like "<= ==..." between LargeNum classes

it has some sweet operator overloading =D this is the first time I try something like that and couldn't test it much. But it pretty much works.

it still needs to be able to print or convert decimal numbers also adding some other operations for supporting integers, but I will not work on this anymore for this day
taytay
SiCrane
SiCrane
If by "sweet operator overloading" you mean invokes undefined behavior and can return completely wrong values, then yes you have sweet operator overloading. By conventional definitions, not so much. Here's a hint: follow canonical function signatures for overloaded operators unless you have a really good reason not to. Returning a reference to a temporary is really bad idea.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.