BigInteger implementation

I need to implement 1024-bit mathematical operations in CI A simple BigInteger library is implemented, where the integer is stored as an array of "typedef INT UINT1024 [400]", where each element is a single digit. This turned out to be so slow that I decided to implement BigInteger using a 1024-bit UINT64 array: "typedef UINT64 UINT1024 [16]"

so, for example, the number: 1000 is represented as {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1000}, 18446744073709551615 as {0,0 , 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0xFFFFFFFFFFFFFFFF} and 18446744073709551616 as {0,0,0,0,0,0,0, 0,0 , 0,0,0,0,0,0,0,1,0}.

I started writing a function to convert the number of a char array to UINT1024 and UINT1024 to a char array, it worked with the numbers <= 0xFFFFFFFFFFFFFFFFFF. Here is what I did:

void UINT1024_FROMSTRING(UIN1024 Integer,const char szInteger[],UINT Length) {
int c = 15;
UINT64 Result = 0,Operation,Carry = 0;
UINT64 Temp = 1;
while(Length--)
{
    Operation = (szInteger[Length] - '0') * Temp;
    Result   += Operation + Carry;
   /*Overflow ?*/
    if (Result < Operation || Temp == 1000000000000000000)
    {
        Carry  = Result - Operation;
        Result = 0;
        Integer[c--] = 0;
        Temp = 1;
    }
    else Carry = 0;

    Temp *= 10;
}

if (Result || Carry)
{
    /* I DONT KNOW WHAT TO DO HERE ! */
}

while(c--) Integer[c] = 0;}

, , , UINT64 - , 1024 .

PS: !

!


, . :

    void _uint128_mul(UINT64 u,UINT64 v,UINT64 * ui64Hi,UINT64 * ui64Lo)
{
   UINT64 ulo, uhi, vlo, vhi, k, t;
   UINT64 wlo, whi, wt;
   uhi = u >> 32;
   ulo = u & 0xFFFFFFFF;
   vhi = v >> 32;
   vlo = v & 0xFFFFFFFF;
   t = ulo*vlo;    wlo = t & 0xFFFFFFFF;
   k = t >> 32;
   t = uhi*vlo + k;
   whi = t & 0xFFFFFFFF;
   wt = t >> 32;

   t = ulo*vhi + whi;
   k = t >> 32;
   *ui64Lo = (t << 32) + wlo;
   *ui64Hi = uhi*vhi + wt + k;
}

void multiply(uint1024_t dUInteger,uint1024_t UInteger)
{
    int i = 16;
    UINT64 lo,hi,Carry = 0;

        while(i--)
        {
            _uint128_mul(dUInteger[i],UInteger[15],&hi,&lo);
            dUInteger[i] = lo + Carry;
            Carry = hi;
        }
}

!

+4
3

UINT1024, integer . , , 10 .

+1

, , - . , GMP, , NTL CLN ++. - . Jôrg Arndt ++.

0

, . 1 , .

, , a [i] * b [j] c [i + j]. . c 2N-1, 1024 , a b 512 .

a b N B-1, B = 2 ^ b, c [k] c [N-1] N * (B-1) ^ 2. ,

(2N)*b>=1024
ld(N)+(2b)<=64

b   N   2N*b    ld(N)+2b

32  16  1024    68
24  22  1056    53
28  19  1064    61

, b = 28, B = 1 <


It would be even more suitable for educational purposes to establish B = 10 ^ d, for example. with d = 9, so the conversion from and to string is relatively trivial.

0
source

Source: https://habr.com/ru/post/1529597/


All Articles