Implements BigInteger.
BigInteger impl | Implements BigInteger. |
Copyright | This program is free software. |
Files | |
C-kern/ | Header file BigInteger. |
C-kern/ | Implementation file BigInteger impl. |
Types | |
struct bigint_divstate_t | Export bigint_divstate_t into global namespace. |
bigint_divstate_t | Used in divmod_biginthelper to store current state of division computation. |
bigint_t | |
static variables | |
s_bigint_errtimer | Simulates an error in different functions. |
helper | |
xorsign_biginthelper | Returns the sign of combined bigint_t.sign_and_used_digits fields. |
add_biginthelper | Adds two integers. |
sub_biginthelper | Subtracts two integers. |
mult_biginthelper | Multiplies two numbers with the simple schoolbook algorithm. |
multsplit_biginthelper | Multiplies two big integer numbers and returns the positive result. |
X = pow(UINT32_MAX+1, split) | Multiplying by X means to increment the exponent with X |
div3by2digits_biginthelper | Divides 3 32 bit integer digits by 2 32 bit integer digits. |
submul_biginthelper | Computes ldigits[*]-=nextdigit*rdigits[*] and corrects nextdigits with -1 if necessary. |
divmod_biginthelper | Computes ldigits[0..lnrdigits-1] = divresult * rdigits[0..rnrdigits-1] + modresult. |
divmodui32_biginthelper | Divides lbig by signed divisor. |
lifetime | |
query | |
assign | |
unary operations | |
binary operations | |
3 address operations | |
test |
This program is free software. You can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
© 2012 Jörg Seebohn
Header file BigInteger.
Implementation file BigInteger impl.
typedef struct bigint_divstate_t bigint_divstate_t
Export bigint_divstate_t into global namespace.
struct bigint_divstate_t
Used in divmod_biginthelper to store current state of division computation.
static variables | |
s_bigint_errtimer | Simulates an error in different functions. |
helper | |
xorsign_biginthelper | Returns the sign of combined bigint_t.sign_and_used_digits fields. |
add_biginthelper | Adds two integers. |
sub_biginthelper | Subtracts two integers. |
mult_biginthelper | Multiplies two numbers with the simple schoolbook algorithm. |
multsplit_biginthelper | Multiplies two big integer numbers and returns the positive result. |
X = pow(UINT32_MAX+1, split) | Multiplying by X means to increment the exponent with X |
div3by2digits_biginthelper | Divides 3 32 bit integer digits by 2 32 bit integer digits. |
submul_biginthelper | Computes ldigits[*]-=nextdigit*rdigits[*] and corrects nextdigits with -1 if necessary. |
divmod_biginthelper | Computes ldigits[0..lnrdigits-1] = divresult * rdigits[0..rnrdigits-1] + modresult. |
divmodui32_biginthelper | Divides lbig by signed divisor. |
lifetime | |
query | |
assign | |
unary operations | |
binary operations | |
3 address operations | |
test |
static inline int16_t xorsign_biginthelper( int16_t lsign, int16_t rsign )
Returns the sign of combined bigint_t.sign_and_used_digits fields. The returned value is either < 0 if exactly one of the parameter is negative. The returned value is >= 0 if both parameter are either negative (<0) or positive (>=0).
This function uses bit operations on signed integers which is implementation-defined.
static int sub_biginthelper( bigint_t *restrict * result, const bigint_t * lbig, const bigint_t * rbig )
Subtracts two integers. The sign of lbig is used to determine the sign of the result. If the magnitude of lbig is bigger than rbig (<cmpmagnitude_bigint>) the result has the same sign as lbig else it is reverted.
static void mult_biginthelper( bigint_t * big, uint16_t lnrdigits, const uint32_t * ldigits, uint16_t rnrdigits, const uint32_t * rdigits, const uint16_t exponent )
Multiplies two numbers with the simple schoolbook algorithm.
1. big must be allocated with size == (lnrdigits + rnrdigits) 2. lnrdigits > 0 && rnrdigits > 0 3. lnrdigits <= rnrdigits 4. ldigits[lnrdigits-1] != 0 && rdigits[rnrdigits-1] != 0
static int multsplit_biginthelper( bigint_t *restrict * result, uint16_t lnrdigits, const uint32_t * ldigits, uint16_t rnrdigits, const uint32_t * rdigits )
Multiplies two big integer numbers and returns the positive result. The multiplication is done with splitting of numbers to save one multiplication.
1. result must be allocated with size == (lnrdigits + rnrdigits) 2. After skipping of trailing zeros: (lnrdigits > 0 && rnrdigits > 0) 3. (ldigits[lnrdigits-1] != 0 && rdigits[rnrdigits-1] != 0)
static void div3by2digits_biginthelper( bigint_divstate_t * state )
Divides 3 32 bit integer digits by 2 32 bit integer digits. The returned number in nextdigit is ((((uint128_t)dividend << 32) + nextdigit) / divisor). The returned value is used to estimate the next digit of the quotient. It is either correct or one too large.
After return the dividend contains the remainder of the division also.
1. dividend < divisor ==> nextdigit <= UINT32_MAX 2. dividend > UINT32_MAX && divisor > UINT32_MAX ==> “nextdigit either correct or one too large”
static void submul_biginthelper( bigint_divstate_t * state )
Computes ldigits[*]-=nextdigit*rdigits[*] and corrects nextdigits with -1 if necessary. The factor nextdigit is corrected in case it is too high (see first precondition).
Use nextdigit == UINT32_MAX and assume that correction is not needed. This is called after nextdigit is corrected from 1 to 0 ==> dividend == divisor. The next step is to compute ((dividend * (UINT32_MAX+1)) + nextdigit) / divisor which would result in UINT32_MAX+1 and can not be represented with nextdigit. But with the previous correction from 1 to 0 we already know that factor (UINT32_MAX+1) is too big and UINT32_MAX is the correct choice. But calculating (with dividend==divisor)
dividend = ((dividend * (UINT32_MAX+1)) + nextdigit) - UINT32_MAX * divisor
results in
dividend = dividend + nextdigit
which could overflow dividend. In the case of overflow the carry bit is ignored. In the implementation the computation subtracts a correction value from dividend but a possible underflow is ignored cause if the missing carry bit. But we already know UINT32_MAX is the correct next digit.
No multiplication needed and returned corrected nextdigit could become 0.
1. (nextdigit+1)*rdigits[*] > ldigits[*] 2. (nextdigit*rdigits[*]) <= ldigits[*] || (nextdigit-1)*rdigits[*] <= ldigits[*]
static void divmod_biginthelper( bigint_t *restrict * divresult, bigint_t *restrict * modresult, uint16_t divnrdigits, // number of digits which must be computed const uint16_t modnrdigits, // number of digits of the remainder const int16_t divsign, // sign ([-1,+1]) of divresult const int16_t lsign, // sign ([-1,+1]) of ldigits (which is the sign of modresult) const uint16_t lnrdigits, // the number of digits in array ldigits uint32_t * ldigits, // the array of digits for the left operand const uint16_t rnrdigits, // the number of digits in array rdigits const uint32_t * rdigits ) // the array of digits for the right operand
Computes ldigits[0..lnrdigits-1] = divresult * rdigits[0..rnrdigits-1] + modresult. After return divresult contains the result of
ldigits[0..lnrdigits-1]/rdigits[0..rnrdigits-1]
and modresult contains the result of
ldigits[0..lnrdigits-1] - divresult * rdigits[0..rnrdigits-1].
1. rnrdigits >= 2 2. lnrdigits >= rnrdigits 3. divnrdigits > 0 && modnrdigits >= 2 && modnrdigits <= lnrdigits 4. (divnrdigits != 1) || (modnrdigits == lnrdigits) 5. divresult == 0 || divresult->allocated_digits >= divnrdigits 6. divresult == 0 || is_valid(divresult->exponent) 7. modresult == 0 || modresult->allocated_digits >= modnrdigits 8. modresult == 0 || is_valid(modresult->exponent)
static void divmodui32_biginthelper( bigint_t *restrict * divresult, bigint_t *restrict * modresult, uint16_t divnrdigits, const int16_t divsign, const int16_t lsign, uint16_t lnrdigits, const uint32_t * const ldigits, const uint32_t divisor )
Divides lbig by signed divisor. The result numbers must be preallocated with correct size. See »Preconditions« item 4. and 5. for the expected size. The sign of divresult is set to divsign and the sign of modresult is set to the same sign as lbig.
1. lnrdigits > 0 2. divisor > 0 3. divnrdigits > 0 4. divresult == 0 || divresult->allocated_digits >= divnrdigits 5. modresult == 0 || modresult->allocated_digits >= max(1, (lnrdigits - (divnrdigits-1))) 6. divresult == 0 || is_valid(divresult->exponent) 7. modresult == 0 || is_valid(modresult->exponent)
Export bigint_divstate_t into global namespace.
typedef struct bigint_divstate_t bigint_divstate_t
Used in divmod_biginthelper to store current state of division computation.
struct bigint_divstate_t
Computes ldigits[0..lnrdigits-1] = divresult * rdigits[0..rnrdigits-1] + modresult.
static void divmod_biginthelper( bigint_t *restrict * divresult, bigint_t *restrict * modresult, uint16_t divnrdigits, // number of digits which must be computed const uint16_t modnrdigits, // number of digits of the remainder const int16_t divsign, // sign ([-1,+1]) of divresult const int16_t lsign, // sign ([-1,+1]) of ldigits (which is the sign of modresult) const uint16_t lnrdigits, // the number of digits in array ldigits uint32_t * ldigits, // the array of digits for the left operand const uint16_t rnrdigits, // the number of digits in array rdigits const uint32_t * rdigits ) // the array of digits for the right operand
Simulates an error in different functions.
static test_errortimer_t s_bigint_errtimer
Returns the sign of combined bigint_t.sign_and_used_digits fields.
static inline int16_t xorsign_biginthelper( int16_t lsign, int16_t rsign )
The absolute value of this number is the number of valid digits.
int16_t sign_and_used_digits
Adds two integers.
static int add_biginthelper( bigint_t *restrict * result, const bigint_t * lbig, const bigint_t * rbig )
Subtracts two integers.
static int sub_biginthelper( bigint_t *restrict * result, const bigint_t * lbig, const bigint_t * rbig )
Multiplies two numbers with the simple schoolbook algorithm.
static void mult_biginthelper( bigint_t * big, uint16_t lnrdigits, const uint32_t * ldigits, uint16_t rnrdigits, const uint32_t * rdigits, const uint16_t exponent )
Multiplies two big integer numbers and returns the positive result.
static int multsplit_biginthelper( bigint_t *restrict * result, uint16_t lnrdigits, const uint32_t * ldigits, uint16_t rnrdigits, const uint32_t * rdigits )
Divides 3 32 bit integer digits by 2 32 bit integer digits.
static void div3by2digits_biginthelper( bigint_divstate_t * state )
Computes ldigits[*]-=nextdigit*rdigits[*] and corrects nextdigits with -1 if necessary.
static void submul_biginthelper( bigint_divstate_t * state )
Divides lbig by signed divisor.
static void divmodui32_biginthelper( bigint_t *restrict * divresult, bigint_t *restrict * modresult, uint16_t divnrdigits, const int16_t divsign, const int16_t lsign, uint16_t lnrdigits, const uint32_t * const ldigits, const uint32_t divisor )