aboutsummaryrefslogtreecommitdiff
path: root/BigInt.c
diff options
context:
space:
mode:
Diffstat (limited to 'BigInt.c')
-rw-r--r--BigInt.c89
1 files changed, 89 insertions, 0 deletions
diff --git a/BigInt.c b/BigInt.c
index b9239d7..4ffee57 100644
--- a/BigInt.c
+++ b/BigInt.c
@@ -74,6 +74,11 @@ B_newstr(MemoryManager *mm, const char* str) {
}
BigInt
+B_newbytes(MemoryManager *mm, usize bytes) {
+ return B_start(mm, 1 + (bytes - 1) / sizeof(UWord));
+}
+
+BigInt
B_dup(MemoryManager *mm, BigInt bigint) {
if (NULL == bigint)
return NULL;
@@ -196,6 +201,90 @@ B_sub(BigInt *inta, BigInt intb) {
return R_Ok;
}
+Result
+B_rshift(BigInt *intx, usize shift) {
+ if (NULL == intx || NULL == *intx)
+ return R_NullArgument;
+
+ if (shift == 0)
+ return R_Ok;
+
+ struct BigIntMeta *bim = B_metadata(*intx);
+ UWord *x = *intx;
+
+ usize word_moves = shift / (sizeof(UWord) * 8);
+ if (word_moves) {
+ usize w = 0;
+ for (; w < bim->words - word_moves; ++w)
+ x[w] = x[w + word_moves];
+ for (; w < bim->words; ++w)
+ x[w] = 0;
+ }
+
+ usize bit_moves = shift % (sizeof(UWord) * 8);
+ if (bit_moves == 1) {
+ x[0] >>= 1;
+ for (usize w = 1; w < bim->words; ++w) {
+ x[w - 1] |= (x[w] & 1) << (sizeof(UWord) * 8 - 1);
+ x[w] >>= 1;
+ }
+ }
+ else if (bit_moves > 1) {
+ UWord mask = ((UWord)1 << bit_moves) - 1;
+
+ x[0] >>= bit_moves;
+ for (usize w = 1; w < bim->words; ++w) {
+ x[w - 1] |= (x[w] & mask) << (sizeof(UWord) * 8 - bit_moves);
+ x[w] >>= bit_moves;
+ }
+ }
+
+ return R_Ok;
+}
+
+Result
+B_lshift(BigInt *intx, usize shift) {
+ if (NULL == intx || NULL == *intx)
+ return R_NullArgument;
+
+ if (shift == 0)
+ return R_Ok;
+
+ struct BigIntMeta *bim = B_metadata(*intx);
+ UWord *x = *intx;
+
+ usize word_moves = shift / (sizeof(UWord) * 8);
+ if (word_moves) {
+ usize w = bim->words - 1;
+ for (; w >= word_moves; --w)
+ x[w] = x[w - word_moves];
+ for (; w < bim->words; --w)
+ x[w] = 0;
+ }
+
+ usize bit_moves = shift % (sizeof(UWord) * 8);
+ if (bit_moves == 1) {
+ UWord mask = (UWord)1 << (sizeof(UWord) * 8 - 1);
+
+ x[bim->words - 1] <<= 1;
+ for (usize w = bim->words - 2; w < bim->words; --w) {
+ x[w + 1] |= (x[w] & mask) >> (sizeof(UWord) * 8 - 1);
+ x[w] <<= 1;
+ }
+ }
+ else if (bit_moves > 1) {
+ UWord mask = (((UWord)1 << bit_moves) - 1) << (sizeof(UWord) * 8 - bit_moves);
+
+ x[bim->words - 1] <<= bit_moves;
+ for (usize w = bim->words - 2; w < bim->words; --w) {
+ x[w + 1] |= (x[w] & mask) >> (sizeof(UWord) * 8 - bit_moves);
+ x[w] <<= bit_moves;
+ }
+ }
+
+ return R_Ok;
+}
+
/* Get */
usize