diff options
| author | Mikhail Romanko <me@blankhex.com> | 2024-06-24 21:31:18 +0300 |
|---|---|---|
| committer | Mikhail Romanko <me@blankhex.com> | 2024-06-24 21:31:18 +0300 |
| commit | d0cd2c4697605ca7260b1db428673b07676a20cb (patch) | |
| tree | ae17a88f83d4f3f23210eaac07c22cc904714a54 | |
| parent | a99724e93446c96581d379a3cecc2da7453acaa6 (diff) | |
| download | bhlib-old-d0cd2c4697605ca7260b1db428673b07676a20cb.tar.gz | |
Add big integer function to quickly generate power of 10 number
| -rw-r--r-- | include/bh/bigint.h | 3 | ||||
| -rw-r--r-- | src/bigint.c | 129 |
2 files changed, 132 insertions, 0 deletions
diff --git a/include/bh/bigint.h b/include/bh/bigint.h index c9cd6e0..5d0833d 100644 --- a/include/bh/bigint.h +++ b/include/bh/bigint.h @@ -92,6 +92,9 @@ int bh_bigint_pow(bh_bigint_t *to, bh_bigint_t *from, bh_uint32_t power); +int bh_bigint_pow10(bh_bigint_t *to, + bh_uint32_t power); + int bh_bigint_powm(bh_bigint_t *to, bh_bigint_t *left, bh_bigint_t *right, diff --git a/src/bigint.c b/src/bigint.c index c78503d..a935461 100644 --- a/src/bigint.c +++ b/src/bigint.c @@ -796,6 +796,135 @@ finish: return code; } +#if defined(BH_BIGINT_LONG) +const size_t bh_bigint_pow10_e[] = +{ + 512, 256, 128, 64, 32, 16, 8, 4, 2, 1 +}; + +const size_t bh_bigint_pow10_size[] = +{ + 55, 28, 14, 7, 4, 2, 1, 1, 1, 1 +}; + +const size_t bh_bigint_pow10_offset[] = +{ + 0, 55, 83, 97, 104, 108, 110, 111, 112, 113 +}; + +const BH_BIGINT_TYPE bh_bigint_pow10_data[] = +{ + 0x00000000ul, 0x00000000ul, 0x00000000ul, 0x00000000ul, + 0x00000000ul, 0x00000000ul, 0x00000000ul, 0x00000000ul, + 0x00000000ul, 0x00000000ul, 0x00000000ul, 0x00000000ul, + 0x00000000ul, 0x00000000ul, 0x00000000ul, 0x00000000ul, + 0x78010000ul, 0x64CFF8D9ul, 0x1B71DFC9ul, 0x3B7C7CAAul, + 0x2975D969ul, 0x5B370751ul, 0x44F0C786ul, 0x23A36202ul, + 0x4194E657ul, 0x739112EDul, 0x6D11D6D5ul, 0x7947C399ul, + 0x1AA1DA1Bul, 0x4E07DA64ul, 0x078973FAul, 0x590D1791ul, + 0x3C51FB2Eul, 0x2DC29EBBul, 0x7E8FB6B2ul, 0x14E2BD75ul, + 0x7FC71533ul, 0x7F80D2BCul, 0x6A464930ul, 0x2FB1AF42ul, + 0x108EE0F9ul, 0x575BC965ul, 0x19CCAA4Eul, 0x4BBAE09Bul, + 0x65B0E944ul, 0x75F58D37ul, 0x6F205CD0ul, 0x0EA3584Cul, + 0x174845A7ul, 0x660744D3ul, 0x7C4E32C1ul, 0x54BC5058ul, + 0x0D98CAB8ul, 0x3A983A47ul, 0x0718CD05ul, 0x00000000ul, + 0x00000000ul, 0x00000000ul, 0x00000000ul, 0x00000000ul, + 0x00000000ul, 0x00000000ul, 0x00000000ul, 0x2E7C0100ul, + 0x270EB730ul, 0x667DCAFBul, 0x297C3EC6ul, 0x650C6121ul, + 0x4DCE0D7Bul, 0x7603F3D2ul, 0x38B76ACAul, 0x66B026B2ul, + 0x6C495B8Cul, 0x4D687454ul, 0x2071E216ul, 0x3C063FF5ul, + 0x62F98AAEul, 0x3C997E7Bul, 0x7BAADE14ul, 0x5C80DCC7ul, + 0x1DE8DDDBul, 0x5D7F73BFul, 0x00002A9Ful, 0x00000000ul, + 0x00000000ul, 0x00000000ul, 0x00000000ul, 0x6953E010ul, + 0x7BF32125ul, 0x454E3F40ul, 0x3A721787ul, 0x4FF5EC23ul, + 0x09B811A7ul, 0x36C36B10ul, 0x1BF8CDE6ul, 0x72603A63ul, + 0x0049DD23ul, 0x00000000ul, 0x00000000ul, 0x7DA87C04ul, + 0x71C76B25ul, 0x2A797ED6ul, 0x27FF3E9Bul, 0x0613C0FAul, + 0x00000000ul, 0x0B59DF02ul, 0x35B5056Eul, 0x00002771ul, + 0x6FC10000ul, 0x00470DE4ul, 0x05F5E100ul, 0x00002710ul, + 0x00000064ul, 0x0000000Aul +}; +#else +const size_t bh_bigint_pow10_e[] = +{ + 512, 256, 128, 64, 32, 16, 8, 4, 2, 1 +}; +const size_t bh_bigint_pow10_size[] = +{ + 114, 57, 29, 15, 8, 4, 2, 1, 1, 1 +}; +const size_t bh_bigint_pow10_offset[] = +{ + 0, 114, 171, 200, 215, 223, 227, 229, 230, 231 +}; +const BH_BIGINT_TYPE bh_bigint_pow10_data[] = +{ + 0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x0000u, + 0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x0000u, + 0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x0000u, + 0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x0000u, + 0x0000u, 0x0000u, 0x6004u, 0x6367u, 0x267Fu, 0x7E4Eu, 0x371Du, 0x4AA3u, + 0x6F8Fu, 0x2D2Eu, 0x5D76u, 0x5454u, 0x1B83u, 0x435Bu, 0x70C7u, 0x0289u, + 0x46C4u, 0x2E8Eu, 0x5399u, 0x360Cu, 0x0897u, 0x2F39u, 0x1D6Du, 0x1DA2u, + 0x7873u, 0x7E51u, 0x7686u, 0x0D50u, 0x6D32u, 0x4E07u, 0x73FAu, 0x0F12u, + 0x2F22u, 0x6434u, 0x6CBAu, 0x628Fu, 0x75DBu, 0x5C29u, 0x6B25u, 0x51F6u, + 0x2EBFu, 0x38AFu, 0x4CCAu, 0x638Au, 0x5E7Fu, 0x00D2u, 0x30FFu, 0x0C92u, + 0x05A9u, 0x46BDu, 0x657Du, 0x7707u, 0x2908u, 0x3C96u, 0x6AEBu, 0x1549u, + 0x6673u, 0x3826u, 0x25DDu, 0x74A2u, 0x65B0u, 0x0D37u, 0x6BEBu, 0x39A1u, + 0x3C81u, 0x6133u, 0x751Au, 0x2D38u, 0x7484u, 0x4D32u, 0x40E8u, 0x5839u, + 0x138Cu, 0x163Eu, 0x5E28u, 0x5C54u, 0x18CAu, 0x471Bu, 0x3074u, 0x0AEAu, + 0x6334u, 0x0038u, 0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x0000u, + 0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x0000u, + 0x0000u, 0x0000u, 0x0000u, 0x7802u, 0x60B9u, 0x3ADCu, 0x6D38u, 0x6E57u, + 0x3667u, 0x43ECu, 0x152Fu, 0x0C24u, 0x7943u, 0x035Eu, 0x26E7u, 0x79E9u, + 0x7603u, 0x6ACAu, 0x716Eu, 0x4D64u, 0x1AC0u, 0x6E33u, 0x624Au, 0x22A6u, + 0x5687u, 0x2169u, 0x0E3Cu, 0x7EA8u, 0x018Fu, 0x2B9Eu, 0x7CC5u, 0x3DE2u, + 0x197Eu, 0x1479u, 0x55BCu, 0x0FEEu, 0x0373u, 0x6EE4u, 0x46EEu, 0x79DEu, + 0x773Bu, 0x7BAFu, 0x0553u, 0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x0000u, + 0x0000u, 0x0000u, 0x0000u, 0x0100u, 0x2A7Cu, 0x24BAu, 0x7CC8u, 0x503Du, + 0x271Fu, 0x43C5u, 0x7217u, 0x2374u, 0x6BD8u, 0x4F3Fu, 0x6046u, 0x404Du, + 0x1B58u, 0x336Cu, 0x0CDEu, 0x337Fu, 0x074Cu, 0x7C98u, 0x7748u, 0x0024u, + 0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x7010u, 0x6D43u, 0x592Fu, 0x1C76u, + 0x6D6Eu, 0x4F2Fu, 0x536Au, 0x7FCFu, 0x3E93u, 0x09E0u, 0x0006u, 0x0000u, + 0x0000u, 0x3E04u, 0x2D67u, 0x15B8u, 0x2DA8u, 0x3B8Bu, 0x0002u, 0x0000u, + 0x5F82u, 0x1BC9u, 0x011Cu, 0x6100u, 0x0BEBu, 0x2710u, 0x0064u, 0x000Au +}; +#endif + +int bh_bigint_pow10(bh_bigint_t *to, + bh_uint32_t power) +{ + size_t index; + + /* Check if exponent withing lookup index range (times 2) */ + if ((power >= 1024) || 0) + { + bh_bigint_set_int(to, 10); + return bh_bigint_pow(to, to, power); + } + + /* Use lookup table */ + bh_bigint_set_int(to, 1); + for (index = 0; (index < sizeof(bh_bigint_pow10_e) / sizeof(size_t)) || power; index++) + { + if (power >= bh_bigint_pow10_e[index]) + { + bh_bigint_t tmp; + + tmp.data = &bh_bigint_pow10_data[bh_bigint_pow10_offset[index]]; + tmp.capacity = bh_bigint_pow10_size[index]; + tmp.size = bh_bigint_pow10_size[index]; + tmp.type = 1; + tmp.error = 0; + + bh_bigint_mul(to, to, &tmp); + power -= bh_bigint_pow10_e[index]; + } + } + + return BH_OK; +} + int bh_bigint_powm(bh_bigint_t *to, bh_bigint_t *left, bh_bigint_t *right, |
