Page 1 of 1

(C++) Subdivision of very large integers

Posted: Mon Jun 09, 2008 5:41 am
by AndrewAPrice
I'm looking for a template class or library that can handle large numbers (up to 1024-bit), which I can subdivide in a fashion like this:

Code: Select all

union
{
    u_int<1024> MyBigNumber;
    struct
    {
          u_int<512> TopHalfOfBigNumber;
          union
          {
                u_int<512> BottomHalfOfBigNumber;
                struct
                {
                      u_int<256> TopHalfofBottomHalf;
                      u_int<256> BottomHalfofBottomHalf;
                };
           }
    };
};
Nearly all the libraries I found that deal with large numbers don't document how they internally store their data.

I'm working with unsigned ints, signed ints, and floats and need addition, subtraction, division, and multiplication. I'm thinking of writing my own template class to do this, but I would like some one to point me in the right direction.

An alternative way would be a class which points to an area of memory. E.g.

Code: Select all

Integer myInt(0x12345 /* address of integer */, 1024 /* how big the integer is */);
And it will perform operations on that area of memory.

Posted: Mon Jun 09, 2008 5:48 am
by JamesM
Libgmp would probably be a good place to look.

(Templating on integer size is going to produce some nastily bloated code, btw.)

Posted: Mon Jun 09, 2008 7:56 am
by AndrewAPrice
JamesM wrote:Libgmp would probably be a good place to look.
It doesn't seem to work with unsigned integers though :(
JamesM wrote:(Templating on integer size is going to produce some nastily bloated code, btw.)
Yeah I realised that.

I've decided the best way would be to find a library that can work with a block of memory. E.g. At address x a variable of size n bytes exists. Then I can manually divide memory up as I please using pointer arithmetic.

I'm looking for a library that supports unsigned ints, signed ints, and floats.

Posted: Mon Jun 09, 2008 8:09 am
by JamesM
MessiahAndrw wrote:
JamesM wrote:Libgmp would probably be a good place to look.
It doesn't seem to work with unsigned integers though :(
JamesM wrote:(Templating on integer size is going to produce some nastily bloated code, btw.)
Yeah I realised that.

I've decided the best way would be to find a library that can work with a block of memory. E.g. At address x a variable of size n bytes exists. Then I can manually divide memory up as I please using pointer arithmetic.

I'm looking for a library that supports unsigned ints, signed ints, and floats.
A quick poke at the gmp manual revealed this page, on which is a code snippet:

Code: Select all

void
     foo (mpz_t result, const mpz_t param, unsigned long n)
     {
       unsigned long  i;
       mpz_mul_ui (result, param, n);
       for (i = 1; i < n; i++)
         mpz_add_ui (result, result, i*7);
     }
What does that "ui" stand for, do you think? (HINT: probably "unsigned integer" ;) )

PS: Look for libmpfr , the multiprecision floating point library if you want floating point too. Integer and floating point calculations are completely seperate, so it makes sense that they're in two different packages.

Posted: Mon Jun 09, 2008 7:33 pm
by AndrewAPrice
JamesM wrote:A quick poke at the gmp manual revealed this page, on which is a code snippet:

Code: Select all

void
     foo (mpz_t result, const mpz_t param, unsigned long n)
     {
       unsigned long  i;
       mpz_mul_ui (result, param, n);
       for (i = 1; i < n; i++)
         mpz_add_ui (result, result, i*7);
     }
What does that "ui" stand for, do you think? (HINT: probably "unsigned integer" ;) )

PS: Look for libmpfr , the multiprecision floating point library if you want floating point too. Integer and floating point calculations are completely seperate, so it makes sense that they're in two different packages.
There we go! :D

One more issue though; how can I get it to work with a specific area of memory? (e.g. this block of memory is a 16 byte integer)

Posted: Tue Jun 10, 2008 11:20 pm
by os64dev
in the C_PlusPlus there is a section a bout placement new:

if you apply that technique you could do

Code: Select all

void* bignum_address = reinterpret_cast<void*>(0x09fff0000);
BIGNUM* ptr = new (bignum_address) BIGNUM;
BIGNUM& ref  = * new (bignum_address) BIGNUM;
edit: ok sorry if it was not clear do no use ptr and ref both. pick one of the two. ptr gives you pointer access to BIGNUM and ref gives you reference to BIGNUM.
edit: the hardcoded address is an example could be any address

Posted: Wed Jun 11, 2008 2:50 pm
by Candy
os64dev wrote:in the C_PlusPlus there is a section a bout placement new:

if you apply that technique you could do

Code: Select all

void* bignum_address = reinterpret_cast<void*>(0x09fff0000);
BIGNUM* test = new (bignum_address) BIGNUM;
BIGNUM& ref  = * new (bignum_address) BIGNUM;
*gruels* that's a doubly invoked new on the same address. Not to mention hardcoded addresses.