From 7e0b603b78adf4c1704b757da05d085e03afe5f6 Mon Sep 17 00:00:00 2001 From: Syndamia Date: Sat, 23 May 2026 09:56:17 +0300 Subject: feat(BigInt): Implement bit shifts and add math in example --- BigInt.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) (limited to 'BigInt.c') diff --git a/BigInt.c b/BigInt.c index b9239d7..4ffee57 100644 --- a/BigInt.c +++ b/BigInt.c @@ -73,6 +73,11 @@ B_newstr(MemoryManager *mm, const char* str) { return NULL; } +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) @@ -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 -- cgit v1.2.3