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 | |
| parent | 72f791227cf3f0e835e62ff22953c005a40882c6 (diff) | |
| download | foollib-7e0b603b78adf4c1704b757da05d085e03afe5f6.tar foollib-7e0b603b78adf4c1704b757da05d085e03afe5f6.tar.gz foollib-7e0b603b78adf4c1704b757da05d085e03afe5f6.zip | |
feat(BigInt): Implement bit shifts and add math in example
| -rw-r--r-- | BigInt.c | 89 | ||||
| -rw-r--r-- | BigInt.h | 3 | ||||
| -rw-r--r-- | example.c | 26 |
3 files changed, 118 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 @@ -9,6 +9,7 @@ typedef void* BigInt; BigInt B_new(MemoryManager *mm, int value); BigInt B_newstr(MemoryManager *mm, const char* str); +BigInt B_newbytes(MemoryManager *mm, usize bytes); BigInt B_dup(MemoryManager *mm, BigInt bigint); BigInt B_newsum(MemoryManager *mm, BigInt a, BigInt b); @@ -22,6 +23,8 @@ Result B_free(BigInt *bigint); Result B_sum(BigInt *a, BigInt b); Result B_sub(BigInt *a, BigInt b); +Result B_rshift(BigInt *x, usize shift); +Result B_lshift(BigInt *x, usize shift); /* Get */ @@ -3,6 +3,7 @@ #include "Vector.h" #include "String.h" #include "BumpAlloc.h" +#include "BigInt.h" #include <stdio.h> int @@ -42,6 +43,31 @@ main() { PRINT_NOTOK(H_freevals(&tet)); PRINT_NOTOK(H_free(&tet)); + BigInt a = B_new(&g, -1), + b = B_new(&g, 1); + + { + uint_fast32_t *aa = a; + aa[0] = -1; + } + + B_sum(&a, b); + char *astr = B_tostr(&g, a); + printf("a + b = %s\n", astr); + + B_sub(&a, b); + B_sub(&a, b); + astr = B_tostr(&g, a); + printf("a - b = %s\n", astr); + + B_lshift(&a, 30); + astr = B_tostr(&g, a); + printf("a << 30 = %s\n", astr); + + B_rshift(&a, 30); + astr = B_tostr(&g, a); + printf("a >> 30 = %s\n", astr); + PRINT_NOTOK(g.destroy(&g)); PRINT_NOTOK(t.destroy(&t)); PRINT_NOTOK(T.destroy(&T)); |
