diff options
| author | Syndamia <kamen@syndamia.com> | 2026-05-23 09:56:17 +0300 |
|---|---|---|
| committer | Syndamia <kamen@syndamia.com> | 2026-05-23 09:56:17 +0300 |
| commit | 7e0b603b78adf4c1704b757da05d085e03afe5f6 (patch) | |
| tree | 558a05e8ca9c0c7cd2bd27df9d9ed0404f4c66d6 /BigInt.c | |
| parent | 72f791227cf3f0e835e62ff22953c005a40882c6 (diff) | |
| download | foollib-7e0b603b78adf4c1704b757da05d085e03afe5f6.tar foollib-7e0b603b78adf4c1704b757da05d085e03afe5f6.tar.gz foollib-7e0b603b78adf4c1704b757da05d085e03afe5f6.zip | |
feat(BigInt): Implement bit shifts and add math in example
Diffstat (limited to 'BigInt.c')
| -rw-r--r-- | BigInt.c | 89 |
1 files changed, 89 insertions, 0 deletions
@@ -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 |
