LCOV - code coverage report
Current view: top level - src - bigint.cpp (source / functions) Hit Total Coverage
Test: coverage.info.cleaned Lines: 905 1055 85.8 %
Date: 1970-01-01 00:00:01 Functions: 59 61 96.7 %
Branches: 415 560 74.1 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * Copyright (c) 2017 Andrew Kelley
       3                 :            :  *
       4                 :            :  * This file is part of zig, which is MIT licensed.
       5                 :            :  * See http://opensource.org/licenses/MIT
       6                 :            :  */
       7                 :            : 
       8                 :            : #include "bigfloat.hpp"
       9                 :            : #include "bigint.hpp"
      10                 :            : #include "buffer.hpp"
      11                 :            : #include "list.hpp"
      12                 :            : #include "os.hpp"
      13                 :            : #include "softfloat.hpp"
      14                 :            : 
      15                 :            : #include <limits>
      16                 :            : #include <algorithm>
      17                 :            : 
      18                 :            : static uint64_t bigint_as_unsigned(const BigInt *bigint);
      19                 :            : 
      20                 :     867849 : static void bigint_normalize(BigInt *dest) {
      21                 :     867849 :     const uint64_t *digits = bigint_ptr(dest);
      22                 :            : 
      23                 :     867849 :     size_t last_nonzero_digit = SIZE_MAX;
      24         [ +  + ]:    1991448 :     for (size_t i = 0; i < dest->digit_count; i += 1) {
      25                 :    1123599 :         uint64_t digit = digits[i];
      26         [ +  + ]:    1123599 :         if (digit != 0) {
      27                 :     953657 :             last_nonzero_digit = i;
      28                 :            :         }
      29                 :            :     }
      30         [ +  + ]:     867849 :     if (last_nonzero_digit == SIZE_MAX) {
      31                 :       2737 :         dest->is_negative = false;
      32                 :       2737 :         dest->digit_count = 0;
      33                 :            :     } else {
      34                 :     865112 :         dest->digit_count = last_nonzero_digit + 1;
      35         [ +  + ]:     865112 :         if (last_nonzero_digit == 0) {
      36                 :     742589 :             dest->data.digit = digits[0];
      37                 :            :         }
      38                 :            :     }
      39                 :     867849 : }
      40                 :            : 
      41                 :          0 : static uint8_t digit_to_char(uint8_t digit, bool uppercase) {
      42         [ #  # ]:          0 :     if (digit <= 9) {
      43                 :          0 :         return digit + '0';
      44         [ #  # ]:          0 :     } else if (digit <= 35) {
      45         [ #  # ]:          0 :         return (digit - 10) + (uppercase ? 'A' : 'a');
      46                 :            :     } else {
      47                 :          0 :         zig_unreachable();
      48                 :            :     }
      49                 :            : }
      50                 :            : 
      51                 :       1163 : size_t bigint_bits_needed(const BigInt *op) {
      52                 :       1163 :     size_t full_bits = op->digit_count * 64;
      53                 :       1163 :     size_t leading_zero_count = bigint_clz(op, full_bits);
      54                 :       1163 :     size_t bits_needed = full_bits - leading_zero_count;
      55                 :       1163 :     return bits_needed + op->is_negative;
      56                 :            : }
      57                 :            : 
      58                 :      18156 : static void to_twos_complement(BigInt *dest, const BigInt *op, size_t bit_count) {
      59 [ +  + ][ +  + ]:      18156 :     if (bit_count == 0 || op->digit_count == 0) {
      60                 :        172 :         bigint_init_unsigned(dest, 0);
      61                 :        172 :         return;
      62                 :            :     }
      63         [ +  + ]:      17984 :     if (op->is_negative) {
      64                 :        376 :         BigInt negated = {0};
      65                 :        376 :         bigint_negate(&negated, op);
      66                 :            : 
      67                 :        376 :         BigInt inverted = {0};
      68                 :        376 :         bigint_not(&inverted, &negated, bit_count, false);
      69                 :            : 
      70                 :        376 :         BigInt one = {0};
      71                 :        376 :         bigint_init_unsigned(&one, 1);
      72                 :            : 
      73                 :        376 :         bigint_add(dest, &inverted, &one);
      74                 :        376 :         return;
      75                 :            :     }
      76                 :            : 
      77                 :      17608 :     dest->is_negative = false;
      78                 :      17608 :     const uint64_t *op_digits = bigint_ptr(op);
      79         [ +  + ]:      17608 :     if (op->digit_count == 1) {
      80                 :      17160 :         dest->data.digit = op_digits[0];
      81         [ +  + ]:      17160 :         if (bit_count < 64) {
      82                 :       4424 :             dest->data.digit &= (1ULL << bit_count) - 1;
      83                 :            :         }
      84                 :      17160 :         dest->digit_count = 1;
      85                 :      17160 :         bigint_normalize(dest);
      86                 :      17160 :         return;
      87                 :            :     }
      88                 :        448 :     size_t digits_to_copy = bit_count / 64;
      89                 :        448 :     size_t leftover_bits = bit_count % 64;
      90                 :        448 :     dest->digit_count = digits_to_copy + ((leftover_bits == 0) ? 0 : 1);
      91 [ +  + ][ +  - ]:        448 :     if (dest->digit_count == 1 && leftover_bits == 0) {
      92                 :         12 :         dest->data.digit = op_digits[0];
      93         [ -  + ]:         12 :         if (dest->data.digit == 0) dest->digit_count = 0;
      94                 :         12 :         return;
      95                 :            :     }
      96                 :        436 :     dest->data.digits = allocate_nonzero<uint64_t>(dest->digit_count);
      97         [ +  + ]:       1308 :     for (size_t i = 0; i < digits_to_copy; i += 1) {
      98         [ +  - ]:        872 :         uint64_t digit = (i < op->digit_count) ? op_digits[i] : 0;
      99                 :        872 :         dest->data.digits[i] = digit;
     100                 :            :     }
     101         [ -  + ]:        436 :     if (leftover_bits != 0) {
     102         [ #  # ]:          0 :         uint64_t digit = (digits_to_copy < op->digit_count) ? op_digits[digits_to_copy] : 0;
     103                 :          0 :         dest->data.digits[digits_to_copy] = digit & ((1ULL << leftover_bits) - 1);
     104                 :            :     }
     105                 :        436 :     bigint_normalize(dest);
     106                 :            : }
     107                 :            : 
     108                 :   19358126 : static bool bit_at_index(const BigInt *bi, size_t index) {
     109                 :   19358126 :     size_t digit_index = index / 64;
     110         [ +  + ]:   19358126 :     if (digit_index >= bi->digit_count)
     111                 :       1296 :         return false;
     112                 :   19356830 :     size_t digit_bit_index = index % 64;
     113                 :   19356830 :     const uint64_t *digits = bigint_ptr(bi);
     114                 :   19356830 :     uint64_t digit = digits[digit_index];
     115                 :   19356830 :     return ((digit >> digit_bit_index) & 0x1) == 0x1;
     116                 :            : }
     117                 :            : 
     118                 :       8562 : static void from_twos_complement(BigInt *dest, const BigInt *src, size_t bit_count, bool is_signed) {
     119                 :       8562 :     assert(!src->is_negative);
     120                 :            : 
     121 [ +  + ][ +  + ]:       8562 :     if (bit_count == 0 || src->digit_count == 0) {
     122                 :         64 :         bigint_init_unsigned(dest, 0);
     123                 :         64 :         return;
     124                 :            :     }
     125                 :            : 
     126 [ +  + ][ +  + ]:       8498 :     if (is_signed && bit_at_index(src, bit_count - 1)) {
                 [ +  + ]
     127                 :        548 :         BigInt negative_one = {0};
     128                 :        548 :         bigint_init_signed(&negative_one, -1);
     129                 :            : 
     130                 :        548 :         BigInt minus_one = {0};
     131                 :        548 :         bigint_add(&minus_one, src, &negative_one);
     132                 :            : 
     133                 :        548 :         BigInt inverted = {0};
     134                 :        548 :         bigint_not(&inverted, &minus_one, bit_count, false);
     135                 :            : 
     136                 :        548 :         bigint_negate(dest, &inverted);
     137                 :        548 :         return;
     138                 :            : 
     139                 :            :     }
     140                 :            : 
     141                 :       7950 :     bigint_init_bigint(dest, src);
     142                 :            : }
     143                 :            : 
     144                 :    2410399 : void bigint_init_unsigned(BigInt *dest, uint64_t x) {
     145         [ +  + ]:    2410399 :     if (x == 0) {
     146                 :     747765 :         dest->digit_count = 0;
     147                 :     747765 :         dest->is_negative = false;
     148                 :     747765 :         return;
     149                 :            :     }
     150                 :    1662634 :     dest->digit_count = 1;
     151                 :    1662634 :     dest->data.digit = x;
     152                 :    1662634 :     dest->is_negative = false;
     153                 :            : }
     154                 :            : 
     155                 :        580 : void bigint_init_signed(BigInt *dest, int64_t x) {
     156         [ -  + ]:        580 :     if (x >= 0) {
     157                 :          0 :         return bigint_init_unsigned(dest, x);
     158                 :            :     }
     159                 :        580 :     dest->is_negative = true;
     160                 :        580 :     dest->digit_count = 1;
     161                 :        580 :     dest->data.digit = ((uint64_t)(-(x + 1))) + 1;
     162                 :            : }
     163                 :            : 
     164                 :          0 : void bigint_init_data(BigInt *dest, const uint64_t *digits, size_t digit_count, bool is_negative) {
     165         [ #  # ]:          0 :     if (digit_count == 0) {
     166                 :          0 :         return bigint_init_unsigned(dest, 0);
     167         [ #  # ]:          0 :     } else if (digit_count == 1) {
     168                 :          0 :         dest->digit_count = 1;
     169                 :          0 :         dest->data.digit = digits[0];
     170                 :          0 :         dest->is_negative = is_negative;
     171                 :          0 :         bigint_normalize(dest);
     172                 :          0 :         return;
     173                 :            :     }
     174                 :            : 
     175                 :          0 :     dest->digit_count = digit_count;
     176                 :          0 :     dest->is_negative = is_negative;
     177                 :          0 :     dest->data.digits = allocate_nonzero<uint64_t>(digit_count);
     178                 :          0 :     memcpy(dest->data.digits, digits, sizeof(uint64_t) * digit_count);
     179                 :            : 
     180                 :          0 :     bigint_normalize(dest);
     181                 :            : }
     182                 :            : 
     183                 :    1195597 : void bigint_init_bigint(BigInt *dest, const BigInt *src) {
     184         [ +  + ]:    1195597 :     if (src->digit_count == 0) {
     185                 :     184427 :         return bigint_init_unsigned(dest, 0);
     186         [ +  + ]:    1011170 :     } else if (src->digit_count == 1) {
     187                 :     979340 :         dest->digit_count = 1;
     188                 :     979340 :         dest->data.digit = src->data.digit;
     189                 :     979340 :         dest->is_negative = src->is_negative;
     190                 :     979340 :         return;
     191                 :            :     }
     192                 :      31830 :     dest->is_negative = src->is_negative;
     193                 :      31830 :     dest->digit_count = src->digit_count;
     194                 :      31830 :     dest->data.digits = allocate_nonzero<uint64_t>(dest->digit_count);
     195                 :      31830 :     memcpy(dest->data.digits, src->data.digits, sizeof(uint64_t) * dest->digit_count);
     196                 :            : }
     197                 :            : 
     198                 :         48 : void bigint_init_bigfloat(BigInt *dest, const BigFloat *op) {
     199                 :            :     float128_t zero;
     200                 :         48 :     ui32_to_f128M(0, &zero);
     201                 :            : 
     202                 :         48 :     dest->is_negative = f128M_lt(&op->value, &zero);
     203                 :            :     float128_t abs_val;
     204         [ -  + ]:         48 :     if (dest->is_negative) {
     205                 :          0 :         f128M_sub(&zero, &op->value, &abs_val);
     206                 :            :     } else {
     207                 :         48 :         memcpy(&abs_val, &op->value, sizeof(float128_t));
     208                 :            :     }
     209                 :            : 
     210                 :            :     float128_t max_u64;
     211                 :         48 :     ui64_to_f128M(UINT64_MAX, &max_u64);
     212         [ +  - ]:         48 :     if (f128M_le(&abs_val, &max_u64)) {
     213                 :         48 :         dest->digit_count = 1;
     214                 :         48 :         dest->data.digit = f128M_to_ui64(&op->value, softfloat_round_minMag, false);
     215                 :         48 :         bigint_normalize(dest);
     216                 :         48 :         return;
     217                 :            :     }
     218                 :            : 
     219                 :            :     float128_t amt;
     220                 :          0 :     f128M_div(&abs_val, &max_u64, &amt);
     221                 :            :     float128_t remainder;
     222                 :          0 :     f128M_rem(&abs_val, &max_u64, &remainder);
     223                 :            : 
     224                 :          0 :     dest->digit_count = 2;
     225                 :          0 :     dest->data.digits = allocate_nonzero<uint64_t>(dest->digit_count);
     226                 :          0 :     dest->data.digits[0] = f128M_to_ui64(&remainder, softfloat_round_minMag, false);
     227                 :          0 :     dest->data.digits[1] = f128M_to_ui64(&amt, softfloat_round_minMag, false);
     228                 :          0 :     bigint_normalize(dest);
     229                 :            : }
     230                 :            : 
     231                 :     452444 : bool bigint_fits_in_bits(const BigInt *bn, size_t bit_count, bool is_signed) {
     232 [ +  + ][ +  - ]:     452444 :     assert(bn->digit_count != 1 || bn->data.digit != 0);
     233         [ +  + ]:     452444 :     if (bit_count == 0) {
     234                 :        472 :         return bigint_cmp_zero(bn) == CmpEQ;
     235                 :            :     }
     236         [ +  + ]:     451972 :     if (bn->digit_count == 0) {
     237                 :      38810 :         return true;
     238                 :            :     }
     239                 :            : 
     240         [ +  + ]:     413162 :     if (!is_signed) {
     241                 :     361456 :         size_t full_bits = bn->digit_count * 64;
     242                 :     361456 :         size_t leading_zero_count = bigint_clz(bn, full_bits);
     243                 :     361456 :         return bit_count >= full_bits - leading_zero_count;
     244                 :            :     }
     245                 :            : 
     246                 :      51706 :     BigInt one = {0};
     247                 :      51706 :     bigint_init_unsigned(&one, 1);
     248                 :            : 
     249                 :      51706 :     BigInt shl_amt = {0};
     250                 :      51706 :     bigint_init_unsigned(&shl_amt, bit_count - 1);
     251                 :            : 
     252                 :      51706 :     BigInt max_value_plus_one = {0};
     253                 :      51706 :     bigint_shl(&max_value_plus_one, &one, &shl_amt);
     254                 :            : 
     255                 :      51706 :     BigInt max_value = {0};
     256                 :      51706 :     bigint_sub(&max_value, &max_value_plus_one, &one);
     257                 :            : 
     258                 :      51706 :     BigInt min_value = {0};
     259                 :      51706 :     bigint_negate(&min_value, &max_value_plus_one);
     260                 :            : 
     261                 :      51706 :     Cmp min_cmp = bigint_cmp(bn, &min_value);
     262                 :      51706 :     Cmp max_cmp = bigint_cmp(bn, &max_value);
     263                 :            : 
     264 [ +  - ][ +  + ]:     452444 :     return (min_cmp == CmpGT || min_cmp == CmpEQ) && (max_cmp == CmpLT || max_cmp == CmpEQ);
         [ +  - ][ +  + ]
     265                 :            : }
     266                 :            : 
     267                 :      11038 : void bigint_write_twos_complement(const BigInt *big_int, uint8_t *buf, size_t bit_count, bool is_big_endian) {
     268         [ -  + ]:      11038 :     if (bit_count == 0)
     269                 :          0 :         return;
     270                 :            : 
     271                 :      11038 :     BigInt twos_comp = {0};
     272                 :      11038 :     to_twos_complement(&twos_comp, big_int, bit_count);
     273                 :            : 
     274                 :      11038 :     const uint64_t *twos_comp_digits = bigint_ptr(&twos_comp);
     275                 :            : 
     276                 :      11038 :     size_t bits_in_last_digit = bit_count % 64;
     277         [ +  + ]:      11038 :     if (bits_in_last_digit == 0) bits_in_last_digit = 64;
     278                 :      11038 :     size_t bytes_in_last_digit = (bits_in_last_digit + 7) / 8;
     279                 :      11038 :     size_t unwritten_byte_count = 8 - bytes_in_last_digit;
     280                 :            : 
     281         [ +  + ]:      11038 :     if (is_big_endian) {
     282                 :        256 :         size_t last_digit_index = (bit_count - 1) / 64;
     283                 :        256 :         size_t digit_index = last_digit_index;
     284                 :        256 :         size_t buf_index = 0;
     285                 :            :         for (;;) {
     286         [ +  - ]:        288 :             uint64_t x = (digit_index < twos_comp.digit_count) ? twos_comp_digits[digit_index] : 0;
     287                 :            : 
     288                 :        288 :             for (size_t byte_index = 7;;) {
     289                 :       1632 :                 uint8_t byte = x & 0xff;
     290         [ +  + ]:       1632 :                 if (digit_index == last_digit_index) {
     291                 :       1376 :                     buf[buf_index + byte_index - unwritten_byte_count] = byte;
     292         [ +  + ]:       1376 :                     if (byte_index == unwritten_byte_count) break;
     293                 :            :                 } else {
     294                 :        256 :                     buf[buf_index + byte_index] = byte;
     295                 :            :                 }
     296                 :            : 
     297         [ +  + ]:       1376 :                 if (byte_index == 0) break;
     298                 :       1344 :                 byte_index -= 1;
     299                 :       1344 :                 x >>= 8;
     300                 :       1344 :             }
     301                 :            : 
     302         [ +  + ]:        288 :             if (digit_index == 0) break;
     303                 :         32 :             digit_index -= 1;
     304         [ -  + ]:         32 :             if (digit_index == last_digit_index) {
     305                 :          0 :                 buf_index += bytes_in_last_digit;
     306                 :            :             } else {
     307                 :         32 :                 buf_index += 8;
     308                 :            :             }
     309                 :        288 :         }
     310                 :            :     } else {
     311                 :      10782 :         size_t digit_count = (bit_count + 63) / 64;
     312                 :      10782 :         size_t buf_index = 0;
     313         [ +  + ]:      22084 :         for (size_t digit_index = 0; digit_index < digit_count; digit_index += 1) {
     314         [ +  + ]:      11046 :             uint64_t x = (digit_index < twos_comp.digit_count) ? twos_comp_digits[digit_index] : 0;
     315                 :            : 
     316                 :      89742 :             for (size_t byte_index = 0;
     317 [ +  + ][ +  + ]:      89742 :                 byte_index < 8 && (digit_index + 1 < digit_count || byte_index < bytes_in_last_digit);
                 [ +  + ]
     318                 :      78696 :                 byte_index += 1)
     319                 :            :             {
     320                 :      78696 :                 uint8_t byte = x & 0xff;
     321                 :      78696 :                 buf[buf_index] = byte;
     322                 :      78696 :                 buf_index += 1;
     323                 :      78696 :                 x >>= 8;
     324                 :            :             }
     325                 :            :         }
     326                 :            :     }
     327                 :            : }
     328                 :            : 
     329                 :            : 
     330                 :      13234 : void bigint_read_twos_complement(BigInt *dest, const uint8_t *buf, size_t bit_count, bool is_big_endian,
     331                 :            :         bool is_signed)
     332                 :            : {
     333         [ -  + ]:      13234 :     if (bit_count == 0) {
     334                 :          0 :         bigint_init_unsigned(dest, 0);
     335                 :          0 :         return;
     336                 :            :     }
     337                 :            : 
     338                 :      13234 :     dest->digit_count = (bit_count + 63) / 64;
     339                 :            :     uint64_t *digits;
     340         [ +  + ]:      13234 :     if (dest->digit_count == 1) {
     341                 :      12914 :         digits = &dest->data.digit;
     342                 :            :     } else {
     343                 :        320 :         digits = allocate_nonzero<uint64_t>(dest->digit_count);
     344                 :        320 :         dest->data.digits = digits;
     345                 :            :     }
     346                 :            : 
     347                 :      13234 :     size_t bits_in_last_digit = bit_count % 64;
     348         [ +  + ]:      13234 :     if (bits_in_last_digit == 0) {
     349                 :      11198 :         bits_in_last_digit = 64;
     350                 :            :     }
     351                 :      13234 :     size_t bytes_in_last_digit = (bits_in_last_digit + 7) / 8;
     352                 :      13234 :     size_t unread_byte_count = 8 - bytes_in_last_digit;
     353                 :            : 
     354         [ -  + ]:      13234 :     if (is_big_endian) {
     355                 :          0 :         size_t buf_index = 0;
     356                 :          0 :         uint64_t digit = 0;
     357         [ #  # ]:          0 :         for (size_t byte_index = unread_byte_count; byte_index < 8; byte_index += 1) {
     358                 :          0 :             uint8_t byte = buf[buf_index];
     359                 :          0 :             buf_index += 1;
     360                 :          0 :             digit <<= 8;
     361                 :          0 :             digit |= byte;
     362                 :            :         }
     363                 :          0 :         digits[dest->digit_count - 1] = digit;
     364         [ #  # ]:          0 :         for (size_t digit_index = 1; digit_index < dest->digit_count; digit_index += 1) {
     365                 :          0 :             digit = 0;
     366         [ #  # ]:          0 :             for (size_t byte_index = 0; byte_index < 8; byte_index += 1) {
     367                 :          0 :                 uint8_t byte = buf[buf_index];
     368                 :          0 :                 buf_index += 1;
     369                 :          0 :                 digit <<= 8;
     370                 :          0 :                 digit |= byte;
     371                 :            :             }
     372                 :          0 :             digits[dest->digit_count - 1 - digit_index] = digit;
     373                 :            :         }
     374                 :            :     } else {
     375                 :      13234 :         size_t buf_index = 0;
     376         [ +  + ]:      26788 :         for (size_t digit_index = 0; digit_index < dest->digit_count; digit_index += 1) {
     377                 :      13554 :             uint64_t digit = 0;
     378         [ +  + ]:      13554 :             size_t end_byte_index = (digit_index == dest->digit_count - 1) ? bytes_in_last_digit : 8;
     379         [ +  + ]:     112618 :             for (size_t byte_index = 0; byte_index < end_byte_index; byte_index += 1) {
     380                 :      99064 :                 uint64_t byte = buf[buf_index];
     381                 :      99064 :                 buf_index += 1;
     382                 :            : 
     383                 :      99064 :                 digit |= byte << (8 * byte_index);
     384                 :            :             }
     385                 :      13554 :             digits[digit_index] = digit;
     386                 :            :         }
     387                 :            :     }
     388                 :            : 
     389         [ +  + ]:      13234 :     if (is_signed) {
     390                 :       1548 :         bigint_normalize(dest);
     391                 :       1548 :         BigInt tmp = {0};
     392                 :       1548 :         bigint_init_bigint(&tmp, dest);
     393                 :       1548 :         from_twos_complement(dest, &tmp, bit_count, true);
     394                 :            :     } else {
     395                 :      11686 :         dest->is_negative = false;
     396                 :      11686 :         bigint_normalize(dest);
     397                 :            :     }
     398                 :            : }
     399                 :            : 
     400                 :            : #if defined(_MSC_VER)
     401                 :            : static bool add_u64_overflow(uint64_t op1, uint64_t op2, uint64_t *result) {
     402                 :            :    *result = op1 + op2;
     403                 :            :    return *result < op1 || *result < op2;
     404                 :            : }
     405                 :            : 
     406                 :            : static bool sub_u64_overflow(uint64_t op1, uint64_t op2, uint64_t *result) {
     407                 :            :    *result = op1 - op2;
     408                 :            :    return *result > op1;
     409                 :            : }
     410                 :            : 
     411                 :            : bool mul_u64_overflow(uint64_t op1, uint64_t op2, uint64_t *result) {
     412                 :            :     *result = op1 * op2;
     413                 :            : 
     414                 :            :     if (op1 == 0 || op2 == 0)
     415                 :            :         return false;
     416                 :            : 
     417                 :            :     if (op1 > UINT64_MAX / op2)
     418                 :            :         return true;
     419                 :            : 
     420                 :            :     if (op2 > UINT64_MAX / op1)
     421                 :            :         return true;
     422                 :            : 
     423                 :            :     return false;
     424                 :            : }
     425                 :            : #else
     426                 :     390084 : static bool add_u64_overflow(uint64_t op1, uint64_t op2, uint64_t *result) {
     427                 :     390084 :     return __builtin_uaddll_overflow((unsigned long long)op1, (unsigned long long)op2,
     428                 :     390084 :             (unsigned long long *)result);
     429                 :            : }
     430                 :            : 
     431                 :      62831 : static bool sub_u64_overflow(uint64_t op1, uint64_t op2, uint64_t *result) {
     432                 :      62831 :     return __builtin_usubll_overflow((unsigned long long)op1, (unsigned long long)op2,
     433                 :      62831 :             (unsigned long long *)result);
     434                 :            : }
     435                 :            : 
     436                 :        162 : bool mul_u64_overflow(uint64_t op1, uint64_t op2, uint64_t *result) {
     437                 :        162 :     return __builtin_umulll_overflow((unsigned long long)op1, (unsigned long long)op2,
     438                 :        162 :             (unsigned long long *)result);
     439                 :            : }
     440                 :            : #endif
     441                 :            : 
     442                 :     524701 : void bigint_add(BigInt *dest, const BigInt *op1, const BigInt *op2) {
     443         [ +  + ]:     524701 :     if (op1->digit_count == 0) {
     444                 :     524197 :         return bigint_init_bigint(dest, op2);
     445                 :            :     }
     446         [ +  + ]:     428869 :     if (op2->digit_count == 0) {
     447                 :      70709 :         return bigint_init_bigint(dest, op1);
     448                 :            :     }
     449         [ +  + ]:     358160 :     if (op1->is_negative == op2->is_negative) {
     450                 :     294653 :         dest->is_negative = op1->is_negative;
     451                 :            : 
     452                 :     294653 :         const uint64_t *op1_digits = bigint_ptr(op1);
     453                 :     294653 :         const uint64_t *op2_digits = bigint_ptr(op2);
     454                 :     294653 :         bool overflow = add_u64_overflow(op1_digits[0], op2_digits[0], &dest->data.digit);
     455 [ +  + ][ +  - ]:     294653 :         if (overflow == 0 && op1->digit_count == 1 && op2->digit_count == 1) {
                 [ +  + ]
     456                 :     237463 :             dest->digit_count = 1;
     457                 :     237463 :             bigint_normalize(dest);
     458                 :     237463 :             return;
     459                 :            :         }
     460                 :      57190 :         size_t i = 1;
     461                 :      57190 :         uint64_t first_digit = dest->data.digit;
     462                 :      57190 :         dest->data.digits = allocate_nonzero<uint64_t>(max(op1->digit_count, op2->digit_count) + 1);
     463                 :      57190 :         dest->data.digits[0] = first_digit;
     464                 :            : 
     465                 :            :         for (;;) {
     466                 :     133268 :             bool found_digit = false;
     467                 :     133268 :             uint64_t x = overflow;
     468                 :     133268 :             overflow = 0;
     469                 :            : 
     470         [ +  + ]:     133268 :             if (i < op1->digit_count) {
     471                 :      76046 :                 found_digit = true;
     472                 :      76046 :                 uint64_t digit = op1_digits[i];
     473                 :      76046 :                 overflow += add_u64_overflow(x, digit, &x);
     474                 :            :             }
     475                 :            : 
     476         [ +  + ]:     133268 :             if (i < op2->digit_count) {
     477                 :      19385 :                 found_digit = true;
     478                 :      19385 :                 uint64_t digit = op2_digits[i];
     479                 :      19385 :                 overflow += add_u64_overflow(x, digit, &x);
     480                 :            :             }
     481                 :            : 
     482                 :     133268 :             dest->data.digits[i] = x;
     483                 :     133268 :             i += 1;
     484                 :            : 
     485         [ +  + ]:     133268 :             if (!found_digit) {
     486                 :      57190 :                 dest->digit_count = i;
     487                 :      57190 :                 bigint_normalize(dest);
     488                 :      57190 :                 return;
     489                 :            :             }
     490                 :      76078 :         }
     491                 :            :     }
     492                 :            :     const BigInt *op_pos;
     493                 :            :     const BigInt *op_neg;
     494         [ +  + ]:      63507 :     if (op1->is_negative) {
     495                 :       2056 :         op_neg = op1;
     496                 :       2056 :         op_pos = op2;
     497                 :            :     } else {
     498                 :      61451 :         op_pos = op1;
     499                 :      61451 :         op_neg = op2;
     500                 :            :     }
     501                 :            : 
     502                 :      63507 :     BigInt op_neg_abs = {0};
     503                 :      63507 :     bigint_negate(&op_neg_abs, op_neg);
     504                 :            :     const BigInt *bigger_op;
     505                 :            :     const BigInt *smaller_op;
     506   [ +  +  +  - ]:      63507 :     switch (bigint_cmp(op_pos, &op_neg_abs)) {
     507                 :       1192 :         case CmpEQ:
     508                 :       1192 :             bigint_init_unsigned(dest, 0);
     509                 :       1192 :             return;
     510                 :       1784 :         case CmpLT:
     511                 :       1784 :             bigger_op = &op_neg_abs;
     512                 :       1784 :             smaller_op = op_pos;
     513                 :       1784 :             dest->is_negative = true;
     514                 :       1784 :             break;
     515                 :      60531 :         case CmpGT:
     516                 :      60531 :             bigger_op = op_pos;
     517                 :      60531 :             smaller_op = &op_neg_abs;
     518                 :      60531 :             dest->is_negative = false;
     519                 :      60531 :             break;
     520                 :            :     }
     521                 :      62315 :     const uint64_t *bigger_op_digits = bigint_ptr(bigger_op);
     522                 :      62315 :     const uint64_t *smaller_op_digits = bigint_ptr(smaller_op);
     523                 :      62315 :     uint64_t overflow = sub_u64_overflow(bigger_op_digits[0], smaller_op_digits[0], &dest->data.digit);
     524 [ +  + ][ +  - ]:      62315 :     if (overflow == 0 && bigger_op->digit_count == 1 && smaller_op->digit_count == 1) {
                 [ +  + ]
     525                 :      61811 :         dest->digit_count = 1;
     526                 :      61811 :         bigint_normalize(dest);
     527                 :      61811 :         return;
     528                 :            :     }
     529                 :        504 :     uint64_t first_digit = dest->data.digit;
     530                 :        504 :     dest->data.digits = allocate_nonzero<uint64_t>(bigger_op->digit_count);
     531                 :        504 :     dest->data.digits[0] = first_digit;
     532                 :        504 :     size_t i = 1;
     533                 :            : 
     534                 :            :     for (;;) {
     535                 :        516 :         bool found_digit = false;
     536                 :        516 :         uint64_t x = bigger_op_digits[i];
     537                 :        516 :         uint64_t prev_overflow = overflow;
     538                 :        516 :         overflow = 0;
     539                 :            : 
     540         [ -  + ]:        516 :         if (i < smaller_op->digit_count) {
     541                 :          0 :             found_digit = true;
     542                 :          0 :             uint64_t digit = smaller_op_digits[i];
     543                 :          0 :             overflow += sub_u64_overflow(x, digit, &x);
     544                 :            :         }
     545         [ +  + ]:        516 :         if (sub_u64_overflow(x, prev_overflow, &x)) {
     546                 :         12 :             found_digit = true;
     547                 :         12 :             overflow += 1;
     548                 :            :         }
     549                 :        516 :         dest->data.digits[i] = x;
     550                 :        516 :         i += 1;
     551                 :            : 
     552 [ +  + ][ +  - ]:        516 :         if (!found_digit || i >= bigger_op->digit_count)
     553                 :            :             break;
     554                 :         12 :     }
     555                 :        504 :     assert(overflow == 0);
     556                 :        504 :     dest->digit_count = i;
     557                 :        504 :     bigint_normalize(dest);
     558                 :            : }
     559                 :            : 
     560                 :       2184 : void bigint_add_wrap(BigInt *dest, const BigInt *op1, const BigInt *op2, size_t bit_count, bool is_signed) {
     561                 :       2184 :     BigInt unwrapped = {0};
     562                 :       2184 :     bigint_add(&unwrapped, op1, op2);
     563                 :       2184 :     bigint_truncate(dest, &unwrapped, bit_count, is_signed);
     564                 :       2184 : }
     565                 :            : 
     566                 :      62417 : void bigint_sub(BigInt *dest, const BigInt *op1, const BigInt *op2) {
     567                 :      62417 :     BigInt op2_negated = {0};
     568                 :      62417 :     bigint_negate(&op2_negated, op2);
     569                 :      62417 :     return bigint_add(dest, op1, &op2_negated);
     570                 :            : }
     571                 :            : 
     572                 :         88 : void bigint_sub_wrap(BigInt *dest, const BigInt *op1, const BigInt *op2, size_t bit_count, bool is_signed) {
     573                 :         88 :     BigInt op2_negated = {0};
     574                 :         88 :     bigint_negate(&op2_negated, op2);
     575                 :         88 :     return bigint_add_wrap(dest, op1, &op2_negated, bit_count, is_signed);
     576                 :            : }
     577                 :            : 
     578                 :     271532 : static void mul_overflow(uint64_t op1, uint64_t op2, uint64_t *lo, uint64_t *hi) {
     579                 :     271532 :     uint64_t u1 = (op1 & 0xffffffff);
     580                 :     271532 :     uint64_t v1 = (op2 & 0xffffffff);
     581                 :     271532 :     uint64_t t = (u1 * v1);
     582                 :     271532 :     uint64_t w3 = (t & 0xffffffff);
     583                 :     271532 :     uint64_t k = (t >> 32);
     584                 :            : 
     585                 :     271532 :     op1 >>= 32;
     586                 :     271532 :     t = (op1 * v1) + k;
     587                 :     271532 :     k = (t & 0xffffffff);
     588                 :     271532 :     uint64_t w1 = (t >> 32);
     589                 :            : 
     590                 :     271532 :     op2 >>= 32;
     591                 :     271532 :     t = (u1 * op2) + k;
     592                 :     271532 :     k = (t >> 32);
     593                 :            : 
     594                 :     271532 :     *hi = (op1 * op2) + w1 + k;
     595                 :     271532 :     *lo = (t << 32) + w3;
     596                 :     271532 : }
     597                 :            : 
     598                 :      19159 : static void mul_scalar(BigInt *dest, const BigInt *op, uint64_t scalar) {
     599                 :      19159 :     bigint_init_unsigned(dest, 0);
     600                 :            : 
     601                 :            :     BigInt bi_64;
     602                 :      19159 :     bigint_init_unsigned(&bi_64, 64);
     603                 :            : 
     604                 :      19159 :     const uint64_t *op_digits = bigint_ptr(op);
     605                 :      19159 :     size_t i = op->digit_count - 1;
     606                 :            : 
     607                 :            :     for (;;) {
     608                 :            :         BigInt shifted;
     609                 :      42142 :         bigint_shl(&shifted, dest, &bi_64);
     610                 :            : 
     611                 :            :         uint64_t result_scalar;
     612                 :            :         uint64_t carry_scalar;
     613                 :      42142 :         mul_overflow(scalar, op_digits[i], &result_scalar, &carry_scalar);
     614                 :            : 
     615                 :            :         BigInt result;
     616                 :      42142 :         bigint_init_unsigned(&result, result_scalar);
     617                 :            : 
     618                 :            :         BigInt carry;
     619                 :      42142 :         bigint_init_unsigned(&carry, carry_scalar);
     620                 :            : 
     621                 :            :         BigInt carry_shifted;
     622                 :      42142 :         bigint_shl(&carry_shifted, &carry, &bi_64);
     623                 :            : 
     624                 :            :         BigInt tmp;
     625                 :      42142 :         bigint_add(&tmp, &shifted, &carry_shifted);
     626                 :            : 
     627                 :      42142 :         bigint_add(dest, &tmp, &result);
     628                 :            : 
     629         [ +  + ]:      42142 :         if (i == 0) {
     630                 :      19159 :             break;
     631                 :            :         }
     632                 :      22983 :         i -= 1;
     633                 :      22983 :     }
     634                 :      19159 : }
     635                 :            : 
     636                 :     281111 : void bigint_mul(BigInt *dest, const BigInt *op1, const BigInt *op2) {
     637 [ +  + ][ -  + ]:     281111 :     if (op1->digit_count == 0 || op2->digit_count == 0) {
     638                 :     261984 :         return bigint_init_unsigned(dest, 0);
     639                 :            :     }
     640                 :     229390 :     const uint64_t *op1_digits = bigint_ptr(op1);
     641                 :     229390 :     const uint64_t *op2_digits = bigint_ptr(op2);
     642                 :            : 
     643                 :            :     uint64_t carry;
     644                 :     229390 :     mul_overflow(op1_digits[0], op2_digits[0], &dest->data.digit, &carry);
     645 [ +  + ][ +  - ]:     229390 :     if (carry == 0 && op1->digit_count == 1 && op2->digit_count == 1) {
                 [ +  + ]
     646                 :     210263 :         dest->is_negative = (op1->is_negative != op2->is_negative);
     647                 :     210263 :         dest->digit_count = 1;
     648                 :     210263 :         bigint_normalize(dest);
     649                 :     210263 :         return;
     650                 :            :     }
     651                 :            : 
     652                 :      19127 :     bigint_init_unsigned(dest, 0);
     653                 :            : 
     654                 :            :     BigInt bi_64;
     655                 :      19127 :     bigint_init_unsigned(&bi_64, 64);
     656                 :            : 
     657                 :      19127 :     size_t i = op2->digit_count - 1;
     658                 :            :     for (;;) {
     659                 :            :         BigInt shifted;
     660                 :      19159 :         bigint_shl(&shifted, dest, &bi_64);
     661                 :            : 
     662                 :            :         BigInt scalar_result;
     663                 :      19159 :         mul_scalar(&scalar_result, op1, op2_digits[i]);
     664                 :            : 
     665                 :      19159 :         bigint_add(dest, &scalar_result, &shifted);
     666                 :            : 
     667         [ +  + ]:      19159 :         if (i == 0) {
     668                 :      19127 :             break;
     669                 :            :         }
     670                 :         32 :         i -= 1;
     671                 :         32 :     }
     672                 :            : 
     673                 :      19127 :     dest->is_negative = (op1->is_negative != op2->is_negative);
     674                 :      19127 :     bigint_normalize(dest);
     675                 :            : }
     676                 :            : 
     677                 :         32 : void bigint_mul_wrap(BigInt *dest, const BigInt *op1, const BigInt *op2, size_t bit_count, bool is_signed) {
     678                 :         32 :     BigInt unwrapped = {0};
     679                 :         32 :     bigint_mul(&unwrapped, op1, op2);
     680                 :         32 :     bigint_truncate(dest, &unwrapped, bit_count, is_signed);
     681                 :         32 : }
     682                 :            : 
     683                 :            : enum ZeroBehavior {
     684                 :            :   /// \brief The returned value is undefined.
     685                 :            :   ZB_Undefined,
     686                 :            :   /// \brief The returned value is numeric_limits<T>::max()
     687                 :            :   ZB_Max,
     688                 :            :   /// \brief The returned value is numeric_limits<T>::digits
     689                 :            :   ZB_Width
     690                 :            : };
     691                 :            : 
     692                 :            : template <typename T, std::size_t SizeOfT> struct LeadingZerosCounter {
     693                 :            :   static std::size_t count(T Val, ZeroBehavior) {
     694                 :            :     if (!Val)
     695                 :            :       return std::numeric_limits<T>::digits;
     696                 :            : 
     697                 :            :     // Bisection method.
     698                 :            :     std::size_t ZeroBits = 0;
     699                 :            :     for (T Shift = std::numeric_limits<T>::digits >> 1; Shift; Shift >>= 1) {
     700                 :            :       T Tmp = Val >> Shift;
     701                 :            :       if (Tmp)
     702                 :            :         Val = Tmp;
     703                 :            :       else
     704                 :            :         ZeroBits |= Shift;
     705                 :            :     }
     706                 :            :     return ZeroBits;
     707                 :            :   }
     708                 :            : };
     709                 :            : 
     710                 :            : #if __GNUC__ >= 4 || defined(_MSC_VER)
     711                 :            : template <typename T> struct LeadingZerosCounter<T, 4> {
     712                 :         96 :   static std::size_t count(T Val, ZeroBehavior ZB) {
     713 [ +  - ][ -  + ]:         96 :     if (ZB != ZB_Undefined && Val == 0)
     714                 :          0 :       return 32;
     715                 :            : 
     716                 :            : #if defined(_MSC_VER)
     717                 :            :     unsigned long Index;
     718                 :            :     _BitScanReverse(&Index, Val);
     719                 :            :     return Index ^ 31;
     720                 :            : #else
     721                 :         96 :     return __builtin_clz(Val);
     722                 :            : #endif
     723                 :            :   }
     724                 :            : };
     725                 :            : 
     726                 :            : #if !defined(_MSC_VER) || defined(_M_X64)
     727                 :            : template <typename T> struct LeadingZerosCounter<T, 8> {
     728                 :            :   static std::size_t count(T Val, ZeroBehavior ZB) {
     729                 :            :     if (ZB != ZB_Undefined && Val == 0)
     730                 :            :       return 64;
     731                 :            : 
     732                 :            : #if defined(_MSC_VER)
     733                 :            :     unsigned long Index;
     734                 :            :     _BitScanReverse64(&Index, Val);
     735                 :            :     return Index ^ 63;
     736                 :            : #else
     737                 :            :     return __builtin_clzll(Val);
     738                 :            : #endif
     739                 :            :   }
     740                 :            : };
     741                 :            : #endif
     742                 :            : #endif
     743                 :            : 
     744                 :            : /// \brief Count number of 0's from the most significant bit to the least
     745                 :            : ///   stopping at the first 1.
     746                 :            : ///
     747                 :            : /// Only unsigned integral types are allowed.
     748                 :            : ///
     749                 :            : /// \param ZB the behavior on an input of 0. Only ZB_Width and ZB_Undefined are
     750                 :            : ///   valid arguments.
     751                 :            : template <typename T>
     752                 :         96 : std::size_t countLeadingZeros(T Val, ZeroBehavior ZB = ZB_Width) {
     753                 :            :   static_assert(std::numeric_limits<T>::is_integer &&
     754                 :            :                     !std::numeric_limits<T>::is_signed,
     755                 :            :                 "Only unsigned integral types are allowed.");
     756                 :         96 :   return LeadingZerosCounter<T, sizeof(T)>::count(Val, ZB);
     757                 :            : }
     758                 :            : 
     759                 :            : /// Make a 64-bit integer from a high / low pair of 32-bit integers.
     760                 :        496 : constexpr inline uint64_t Make_64(uint32_t High, uint32_t Low) {
     761                 :        496 :   return ((uint64_t)High << 32) | (uint64_t)Low;
     762                 :            : }
     763                 :            : 
     764                 :            : /// Return the high 32 bits of a 64 bit value.
     765                 :       1600 : constexpr inline uint32_t Hi_32(uint64_t Value) {
     766                 :       1600 :   return static_cast<uint32_t>(Value >> 32);
     767                 :            : }
     768                 :            : 
     769                 :            : /// Return the low 32 bits of a 64 bit value.
     770                 :       1984 : constexpr inline uint32_t Lo_32(uint64_t Value) {
     771                 :       1984 :   return static_cast<uint32_t>(Value);
     772                 :            : }
     773                 :            : 
     774                 :            : /// Implementation of Knuth's Algorithm D (Division of nonnegative integers)
     775                 :            : /// from "Art of Computer Programming, Volume 2", section 4.3.1, p. 272. The
     776                 :            : /// variables here have the same names as in the algorithm. Comments explain
     777                 :            : /// the algorithm and any deviation from it.
     778                 :         96 : static void KnuthDiv(uint32_t *u, uint32_t *v, uint32_t *q, uint32_t* r,
     779                 :            :                      unsigned m, unsigned n)
     780                 :            : {
     781                 :         96 :     assert(u && "Must provide dividend");
     782                 :         96 :     assert(v && "Must provide divisor");
     783                 :         96 :     assert(q && "Must provide quotient");
     784 [ +  - ][ +  - ]:         96 :     assert(u != v && u != q && v != q && "Must use different memory");
                 [ +  - ]
     785                 :         96 :     assert(n>1 && "n must be > 1");
     786                 :            : 
     787                 :            :     // b denotes the base of the number system. In our case b is 2^32.
     788                 :         96 :     const uint64_t b = uint64_t(1) << 32;
     789                 :            : 
     790                 :            :     // D1. [Normalize.] Set d = b / (v[n-1] + 1) and multiply all the digits of
     791                 :            :     // u and v by d. Note that we have taken Knuth's advice here to use a power
     792                 :            :     // of 2 value for d such that d * v[n-1] >= b/2 (b is the base). A power of
     793                 :            :     // 2 allows us to shift instead of multiply and it is easy to determine the
     794                 :            :     // shift amount from the leading zeros.  We are basically normalizing the u
     795                 :            :     // and v so that its high bits are shifted to the top of v's range without
     796                 :            :     // overflow. Note that this can require an extra word in u so that u must
     797                 :            :     // be of length m+n+1.
     798                 :         96 :     unsigned shift = countLeadingZeros(v[n-1]);
     799                 :         96 :     uint32_t v_carry = 0;
     800                 :         96 :     uint32_t u_carry = 0;
     801         [ +  - ]:         96 :     if (shift) {
     802         [ +  + ]:        576 :         for (unsigned i = 0; i < m+n; ++i) {
     803                 :        480 :             uint32_t u_tmp = u[i] >> (32 - shift);
     804                 :        480 :             u[i] = (u[i] << shift) | u_carry;
     805                 :        480 :             u_carry = u_tmp;
     806                 :            :         }
     807         [ +  + ]:        576 :         for (unsigned i = 0; i < n; ++i) {
     808                 :        480 :             uint32_t v_tmp = v[i] >> (32 - shift);
     809                 :        480 :             v[i] = (v[i] << shift) | v_carry;
     810                 :        480 :             v_carry = v_tmp;
     811                 :            :         }
     812                 :            :     }
     813                 :         96 :     u[m+n] = u_carry;
     814                 :            : 
     815                 :            :     // D2. [Initialize j.]  Set j to m. This is the loop counter over the places.
     816                 :         96 :     int j = m;
     817                 :          0 :     do {
     818                 :            :         // D3. [Calculate q'.].
     819                 :            :         //     Set qp = (u[j+n]*b + u[j+n-1]) / v[n-1]. (qp=qprime=q')
     820                 :            :         //     Set rp = (u[j+n]*b + u[j+n-1]) % v[n-1]. (rp=rprime=r')
     821                 :            :         // Now test if qp == b or qp*v[n-2] > b*rp + u[j+n-2]; if so, decrease
     822                 :            :         // qp by 1, increase rp by v[n-1], and repeat this test if rp < b. The test
     823                 :            :         // on v[n-2] determines at high speed most of the cases in which the trial
     824                 :            :         // value qp is one too large, and it eliminates all cases where qp is two
     825                 :            :         // too large.
     826                 :         96 :         uint64_t dividend = Make_64(u[j+n], u[j+n-1]);
     827                 :         96 :         uint64_t qp = dividend / v[n-1];
     828                 :         96 :         uint64_t rp = dividend % v[n-1];
     829 [ -  + ][ +  - ]:         96 :         if (qp == b || qp*v[n-2] > b*rp + u[j+n-2]) {
     830                 :          0 :             qp--;
     831                 :          0 :             rp += v[n-1];
     832 [ #  # ][ #  # ]:          0 :             if (rp < b && (qp == b || qp*v[n-2] > b*rp + u[j+n-2]))
                 [ #  # ]
     833                 :          0 :                 qp--;
     834                 :            :         }
     835                 :            : 
     836                 :            :         // D4. [Multiply and subtract.] Replace (u[j+n]u[j+n-1]...u[j]) with
     837                 :            :         // (u[j+n]u[j+n-1]..u[j]) - qp * (v[n-1]...v[1]v[0]). This computation
     838                 :            :         // consists of a simple multiplication by a one-place number, combined with
     839                 :            :         // a subtraction.
     840                 :            :         // The digits (u[j+n]...u[j]) should be kept positive; if the result of
     841                 :            :         // this step is actually negative, (u[j+n]...u[j]) should be left as the
     842                 :            :         // true value plus b**(n+1), namely as the b's complement of
     843                 :            :         // the true value, and a "borrow" to the left should be remembered.
     844                 :         96 :         int64_t borrow = 0;
     845         [ +  + ]:        576 :         for (unsigned i = 0; i < n; ++i) {
     846                 :        480 :             uint64_t p = uint64_t(qp) * uint64_t(v[i]);
     847                 :        480 :             int64_t subres = int64_t(u[j+i]) - borrow - Lo_32(p);
     848                 :        480 :             u[j+i] = Lo_32(subres);
     849                 :        480 :             borrow = Hi_32(p) - Hi_32(subres);
     850                 :            :         }
     851                 :         96 :         bool isNeg = u[j+n] < borrow;
     852                 :         96 :         u[j+n] -= Lo_32(borrow);
     853                 :            : 
     854                 :            :         // D5. [Test remainder.] Set q[j] = qp. If the result of step D4 was
     855                 :            :         // negative, go to step D6; otherwise go on to step D7.
     856                 :         96 :         q[j] = Lo_32(qp);
     857         [ -  + ]:         96 :         if (isNeg) {
     858                 :            :             // D6. [Add back]. The probability that this step is necessary is very
     859                 :            :             // small, on the order of only 2/b. Make sure that test data accounts for
     860                 :            :             // this possibility. Decrease q[j] by 1
     861                 :          0 :             q[j]--;
     862                 :            :             // and add (0v[n-1]...v[1]v[0]) to (u[j+n]u[j+n-1]...u[j+1]u[j]).
     863                 :            :             // A carry will occur to the left of u[j+n], and it should be ignored
     864                 :            :             // since it cancels with the borrow that occurred in D4.
     865                 :          0 :             bool carry = false;
     866         [ #  # ]:          0 :             for (unsigned i = 0; i < n; i++) {
     867                 :          0 :                 uint32_t limit = std::min(u[j+i],v[i]);
     868                 :          0 :                 u[j+i] += v[i] + carry;
     869 [ #  # ][ #  # ]:          0 :                 carry = u[j+i] < limit || (carry && u[j+i] == limit);
                 [ #  # ]
     870                 :            :             }
     871                 :          0 :             u[j+n] += carry;
     872                 :            :         }
     873                 :            : 
     874                 :            :         // D7. [Loop on j.]  Decrease j by one. Now if j >= 0, go back to D3.
     875         [ -  + ]:         96 :     } while (--j >= 0);
     876                 :            : 
     877                 :            :     // D8. [Unnormalize]. Now q[...] is the desired quotient, and the desired
     878                 :            :     // remainder may be obtained by dividing u[...] by d. If r is non-null we
     879                 :            :     // compute the remainder (urem uses this).
     880         [ +  + ]:         96 :     if (r) {
     881                 :            :         // The value d is expressed by the "shift" value above since we avoided
     882                 :            :         // multiplication by d by using a shift left. So, all we have to do is
     883                 :            :         // shift right here.
     884         [ +  - ]:         32 :         if (shift) {
     885                 :         32 :             uint32_t carry = 0;
     886         [ +  + ]:        192 :             for (int i = n-1; i >= 0; i--) {
     887                 :        160 :                 r[i] = (u[i] >> shift) | carry;
     888                 :        160 :                 carry = u[i] << (32 - shift);
     889                 :            :             }
     890                 :            :         } else {
     891         [ #  # ]:         32 :             for (int i = n-1; i >= 0; i--) {
     892                 :          0 :                 r[i] = u[i];
     893                 :            :             }
     894                 :            :         }
     895                 :            :     }
     896                 :         96 : }
     897                 :            : 
     898                 :            : // Implementation ported from LLVM/lib/Support/APInt.cpp
     899                 :        112 : static void bigint_unsigned_division(const BigInt *op1, const BigInt *op2, BigInt *Quotient, BigInt *Remainder) {
     900                 :        112 :     Cmp cmp = bigint_cmp(op1, op2);
     901         [ -  + ]:        112 :     if (cmp == CmpLT) {
     902         [ #  # ]:          0 :         if (Quotient != nullptr) {
     903                 :          0 :             bigint_init_unsigned(Quotient, 0);
     904                 :            :         }
     905         [ #  # ]:          0 :         if (Remainder != nullptr) {
     906                 :          0 :             bigint_init_bigint(Remainder, op1);
     907                 :            :         }
     908                 :          0 :         return;
     909                 :            :     }
     910         [ -  + ]:        112 :     if (cmp == CmpEQ) {
     911         [ #  # ]:          0 :         if (Quotient != nullptr) {
     912                 :          0 :             bigint_init_unsigned(Quotient, 1);
     913                 :            :         }
     914         [ #  # ]:          0 :         if (Remainder != nullptr) {
     915                 :          0 :             bigint_init_unsigned(Remainder, 0);
     916                 :            :         }
     917                 :          0 :         return;
     918                 :            :     }
     919                 :            : 
     920                 :        112 :     const uint64_t *LHS = bigint_ptr(op1);
     921                 :        112 :     const uint64_t *RHS = bigint_ptr(op2);
     922                 :        112 :     unsigned lhsWords = op1->digit_count;
     923                 :        112 :     unsigned rhsWords = op2->digit_count;
     924                 :            : 
     925                 :            :     // First, compose the values into an array of 32-bit words instead of
     926                 :            :     // 64-bit words. This is a necessity of both the "short division" algorithm
     927                 :            :     // and the Knuth "classical algorithm" which requires there to be native
     928                 :            :     // operations for +, -, and * on an m bit value with an m*2 bit result. We
     929                 :            :     // can't use 64-bit operands here because we don't have native results of
     930                 :            :     // 128-bits. Furthermore, casting the 64-bit values to 32-bit values won't
     931                 :            :     // work on large-endian machines.
     932                 :        112 :     unsigned n = rhsWords * 2;
     933                 :        112 :     unsigned m = (lhsWords * 2) - n;
     934                 :            : 
     935                 :            :     // Allocate space for the temporary values we need either on the stack, if
     936                 :            :     // it will fit, or on the heap if it won't.
     937                 :            :     uint32_t SPACE[128];
     938                 :        112 :     uint32_t *U = nullptr;
     939                 :        112 :     uint32_t *V = nullptr;
     940                 :        112 :     uint32_t *Q = nullptr;
     941                 :        112 :     uint32_t *R = nullptr;
     942 [ +  - ][ +  + ]:        112 :     if ((Remainder?4:3)*n+2*m+1 <= 128) {
     943                 :        112 :         U = &SPACE[0];
     944                 :        112 :         V = &SPACE[m+n+1];
     945                 :        112 :         Q = &SPACE[(m+n+1) + n];
     946         [ +  + ]:        112 :         if (Remainder)
     947                 :         48 :             R = &SPACE[(m+n+1) + n + (m+n)];
     948                 :            :     } else {
     949         [ #  # ]:          0 :         U = new uint32_t[m + n + 1];
     950         [ #  # ]:          0 :         V = new uint32_t[n];
     951         [ #  # ]:          0 :         Q = new uint32_t[m+n];
     952         [ #  # ]:          0 :         if (Remainder)
     953         [ #  # ]:          0 :             R = new uint32_t[n];
     954                 :            :     }
     955                 :            : 
     956                 :            :     // Initialize the dividend
     957                 :        112 :     memset(U, 0, (m+n+1)*sizeof(uint32_t));
     958         [ +  + ]:        448 :     for (unsigned i = 0; i < lhsWords; ++i) {
     959                 :        336 :         uint64_t tmp = LHS[i];
     960                 :        336 :         U[i * 2] = Lo_32(tmp);
     961                 :        336 :         U[i * 2 + 1] = Hi_32(tmp);
     962                 :            :     }
     963                 :        112 :     U[m+n] = 0; // this extra word is for "spill" in the Knuth algorithm.
     964                 :            : 
     965                 :            :     // Initialize the divisor
     966                 :        112 :     memset(V, 0, (n)*sizeof(uint32_t));
     967         [ +  + ]:        416 :     for (unsigned i = 0; i < rhsWords; ++i) {
     968                 :        304 :         uint64_t tmp = RHS[i];
     969                 :        304 :         V[i * 2] = Lo_32(tmp);
     970                 :        304 :         V[i * 2 + 1] = Hi_32(tmp);
     971                 :            :     }
     972                 :            : 
     973                 :            :     // initialize the quotient and remainder
     974                 :        112 :     memset(Q, 0, (m+n) * sizeof(uint32_t));
     975         [ +  + ]:        112 :     if (Remainder)
     976                 :         48 :         memset(R, 0, n * sizeof(uint32_t));
     977                 :            : 
     978                 :            :     // Now, adjust m and n for the Knuth division. n is the number of words in
     979                 :            :     // the divisor. m is the number of words by which the dividend exceeds the
     980                 :            :     // divisor (i.e. m+n is the length of the dividend). These sizes must not
     981                 :            :     // contain any zero words or the Knuth algorithm fails.
     982 [ +  - ][ +  + ]:        224 :     for (unsigned i = n; i > 0 && V[i-1] == 0; i--) {
     983                 :        112 :         n--;
     984                 :        112 :         m++;
     985                 :            :     }
     986 [ +  - ][ +  + ]:        208 :     for (unsigned i = m+n; i > 0 && U[i-1] == 0; i--)
     987                 :         96 :         m--;
     988                 :            : 
     989                 :            :     // If we're left with only a single word for the divisor, Knuth doesn't work
     990                 :            :     // so we implement the short division algorithm here. This is much simpler
     991                 :            :     // and faster because we are certain that we can divide a 64-bit quantity
     992                 :            :     // by a 32-bit quantity at hardware speed and short division is simply a
     993                 :            :     // series of such operations. This is just like doing short division but we
     994                 :            :     // are using base 2^32 instead of base 10.
     995                 :        112 :     assert(n != 0 && "Divide by zero?");
     996         [ +  + ]:        112 :     if (n == 1) {
     997                 :         16 :         uint32_t divisor = V[0];
     998                 :         16 :         uint32_t remainder = 0;
     999         [ +  + ]:        112 :         for (int i = m; i >= 0; i--) {
    1000                 :         96 :             uint64_t partial_dividend = Make_64(remainder, U[i]);
    1001         [ -  + ]:         96 :             if (partial_dividend == 0) {
    1002                 :          0 :                 Q[i] = 0;
    1003                 :          0 :                 remainder = 0;
    1004         [ -  + ]:         96 :             } else if (partial_dividend < divisor) {
    1005                 :          0 :                 Q[i] = 0;
    1006                 :          0 :                 remainder = Lo_32(partial_dividend);
    1007         [ -  + ]:         96 :             } else if (partial_dividend == divisor) {
    1008                 :          0 :                 Q[i] = 1;
    1009                 :          0 :                 remainder = 0;
    1010                 :            :             } else {
    1011                 :         96 :                 Q[i] = Lo_32(partial_dividend / divisor);
    1012                 :         96 :                 remainder = Lo_32(partial_dividend - (Q[i] * divisor));
    1013                 :            :             }
    1014                 :            :         }
    1015         [ +  - ]:         16 :         if (R)
    1016                 :         16 :             R[0] = remainder;
    1017                 :            :     } else {
    1018                 :            :         // Now we're ready to invoke the Knuth classical divide algorithm. In this
    1019                 :            :         // case n > 1.
    1020                 :         96 :         KnuthDiv(U, V, Q, R, m, n);
    1021                 :            :     }
    1022                 :            : 
    1023                 :            :     // If the caller wants the quotient
    1024         [ +  + ]:        112 :     if (Quotient) {
    1025                 :         64 :         Quotient->is_negative = false;
    1026                 :         64 :         Quotient->digit_count = lhsWords;
    1027         [ -  + ]:         64 :         if (lhsWords == 1) {
    1028                 :          0 :             Quotient->data.digit = Make_64(Q[1], Q[0]);
    1029                 :            :         } else {
    1030                 :         64 :             Quotient->data.digits = allocate<uint64_t>(lhsWords);
    1031         [ +  + ]:        256 :             for (size_t i = 0; i < lhsWords; i += 1) {
    1032                 :        192 :                 Quotient->data.digits[i] = Make_64(Q[i*2+1], Q[i*2]);
    1033                 :            :             }
    1034                 :            :         }
    1035                 :            :     }
    1036                 :            : 
    1037                 :            :     // If the caller wants the remainder
    1038         [ +  + ]:        112 :     if (Remainder) {
    1039                 :         48 :         Remainder->is_negative = false;
    1040                 :         48 :         Remainder->digit_count = rhsWords;
    1041         [ +  + ]:         48 :         if (rhsWords == 1) {
    1042                 :         16 :             Remainder->data.digit = Make_64(R[1], R[0]);
    1043                 :            :         } else {
    1044                 :         32 :             Remainder->data.digits = allocate<uint64_t>(rhsWords);
    1045         [ +  + ]:        208 :             for (size_t i = 0; i < rhsWords; i += 1) {
    1046                 :         96 :                 Remainder->data.digits[i] = Make_64(R[i*2+1], R[i*2]);
    1047                 :            :             }
    1048                 :            :         }
    1049                 :            :     }
    1050                 :            : }
    1051                 :            : 
    1052                 :        602 : void bigint_div_trunc(BigInt *dest, const BigInt *op1, const BigInt *op2) {
    1053                 :        602 :     assert(op2->digit_count != 0); // division by zero
    1054         [ +  + ]:        602 :     if (op1->digit_count == 0) {
    1055                 :          8 :         bigint_init_unsigned(dest, 0);
    1056                 :        538 :         return;
    1057                 :            :     }
    1058                 :        594 :     const uint64_t *op1_digits = bigint_ptr(op1);
    1059                 :        594 :     const uint64_t *op2_digits = bigint_ptr(op2);
    1060 [ +  - ][ +  + ]:        594 :     if (op1->digit_count == 1 && op2->digit_count == 1) {
    1061                 :        530 :         dest->data.digit = op1_digits[0] / op2_digits[0];
    1062                 :        530 :         dest->digit_count = 1;
    1063                 :        530 :         dest->is_negative = op1->is_negative != op2->is_negative;
    1064                 :        530 :         bigint_normalize(dest);
    1065                 :        530 :         return;
    1066                 :            :     }
    1067 [ -  + ][ #  # ]:         64 :     if (op2->digit_count == 1 && op2_digits[0] == 1) {
    1068                 :            :         // X / 1 == X
    1069                 :          0 :         bigint_init_bigint(dest, op1);
    1070                 :          0 :         dest->is_negative = op1->is_negative != op2->is_negative;
    1071                 :          0 :         bigint_normalize(dest);
    1072                 :          0 :         return;
    1073                 :            :     }
    1074                 :            : 
    1075                 :            :     const BigInt *op1_positive;
    1076                 :            :     BigInt op1_positive_data;
    1077         [ +  + ]:         64 :     if (op1->is_negative) {
    1078                 :         32 :         bigint_negate(&op1_positive_data, op1);
    1079                 :         32 :         op1_positive = &op1_positive_data;
    1080                 :            :     } else {
    1081                 :         32 :         op1_positive = op1;
    1082                 :            :     }
    1083                 :            : 
    1084                 :            :     const BigInt *op2_positive;
    1085                 :            :     BigInt op2_positive_data;
    1086         [ +  + ]:         64 :     if (op2->is_negative) {
    1087                 :         32 :         bigint_negate(&op2_positive_data, op2);
    1088                 :         32 :         op2_positive = &op2_positive_data;
    1089                 :            :     } else {
    1090                 :         32 :         op2_positive = op2;
    1091                 :            :     }
    1092                 :            : 
    1093                 :         64 :     bigint_unsigned_division(op1_positive, op2_positive, dest, nullptr);
    1094                 :         64 :     dest->is_negative = op1->is_negative != op2->is_negative;
    1095                 :         64 :     bigint_normalize(dest);
    1096                 :            : }
    1097                 :            : 
    1098                 :         80 : void bigint_div_floor(BigInt *dest, const BigInt *op1, const BigInt *op2) {
    1099         [ +  + ]:         80 :     if (op1->is_negative != op2->is_negative) {
    1100                 :         56 :         bigint_div_trunc(dest, op1, op2);
    1101                 :         56 :         BigInt mult_again = {0};
    1102                 :         56 :         bigint_mul(&mult_again, dest, op2);
    1103                 :         56 :         mult_again.is_negative = op1->is_negative;
    1104         [ +  + ]:         56 :         if (bigint_cmp(&mult_again, op1) != CmpEQ) {
    1105                 :         32 :             BigInt tmp = {0};
    1106                 :         32 :             bigint_init_bigint(&tmp, dest);
    1107                 :         32 :             BigInt neg_one = {0};
    1108                 :         32 :             bigint_init_signed(&neg_one, -1);
    1109                 :         32 :             bigint_add(dest, &tmp, &neg_one);
    1110                 :            :         }
    1111                 :         56 :         bigint_normalize(dest);
    1112                 :            :     } else {
    1113                 :         24 :         bigint_div_trunc(dest, op1, op2);
    1114                 :            :     }
    1115                 :         80 : }
    1116                 :            : 
    1117                 :        408 : void bigint_rem(BigInt *dest, const BigInt *op1, const BigInt *op2) {
    1118                 :        408 :     assert(op2->digit_count != 0); // division by zero
    1119         [ -  + ]:        408 :     if (op1->digit_count == 0) {
    1120                 :          0 :         bigint_init_unsigned(dest, 0);
    1121                 :        360 :         return;
    1122                 :            :     }
    1123                 :        408 :     const uint64_t *op1_digits = bigint_ptr(op1);
    1124                 :        408 :     const uint64_t *op2_digits = bigint_ptr(op2);
    1125                 :            : 
    1126 [ +  - ][ +  + ]:        408 :     if (op1->digit_count == 1 && op2->digit_count == 1) {
    1127                 :        360 :         dest->data.digit = op1_digits[0] % op2_digits[0];
    1128                 :        360 :         dest->digit_count = 1;
    1129                 :        360 :         dest->is_negative = op1->is_negative;
    1130                 :        360 :         bigint_normalize(dest);
    1131                 :        360 :         return;
    1132                 :            :     }
    1133 [ -  + ][ #  # ]:         48 :     if (op2->digit_count == 2 && op2_digits[0] == 0 && op2_digits[1] == 1) {
                 [ #  # ]
    1134                 :            :         // special case this divisor
    1135                 :          0 :         bigint_init_unsigned(dest, op1_digits[0]);
    1136                 :          0 :         dest->is_negative = op1->is_negative;
    1137                 :          0 :         bigint_normalize(dest);
    1138                 :          0 :         return;
    1139                 :            :     }
    1140                 :            : 
    1141 [ +  + ][ -  + ]:         48 :     if (op2->digit_count == 1 && op2_digits[0] == 1) {
    1142                 :            :         // X % 1 == 0
    1143                 :          0 :         bigint_init_unsigned(dest, 0);
    1144                 :          0 :         return;
    1145                 :            :     }
    1146                 :            : 
    1147                 :            :     const BigInt *op1_positive;
    1148                 :            :     BigInt op1_positive_data;
    1149         [ +  + ]:         48 :     if (op1->is_negative) {
    1150                 :         16 :         bigint_negate(&op1_positive_data, op1);
    1151                 :         16 :         op1_positive = &op1_positive_data;
    1152                 :            :     } else {
    1153                 :         32 :         op1_positive = op1;
    1154                 :            :     }
    1155                 :            : 
    1156                 :            :     const BigInt *op2_positive;
    1157                 :            :     BigInt op2_positive_data;
    1158         [ -  + ]:         48 :     if (op2->is_negative) {
    1159                 :          0 :         bigint_negate(&op2_positive_data, op2);
    1160                 :          0 :         op2_positive = &op2_positive_data;
    1161                 :            :     } else {
    1162                 :         48 :         op2_positive = op2;
    1163                 :            :     }
    1164                 :            : 
    1165                 :         48 :     bigint_unsigned_division(op1_positive, op2_positive, nullptr, dest);
    1166                 :         48 :     dest->is_negative = op1->is_negative;
    1167                 :         48 :     bigint_normalize(dest);
    1168                 :            : }
    1169                 :            : 
    1170                 :         40 : void bigint_mod(BigInt *dest, const BigInt *op1, const BigInt *op2) {
    1171         [ +  + ]:         40 :     if (op1->is_negative) {
    1172                 :            :         BigInt first_rem;
    1173                 :         24 :         bigint_rem(&first_rem, op1, op2);
    1174                 :         24 :         first_rem.is_negative = !op2->is_negative;
    1175                 :            :         BigInt op2_minus_rem;
    1176                 :         24 :         bigint_add(&op2_minus_rem, op2, &first_rem);
    1177                 :         24 :         bigint_rem(dest, &op2_minus_rem, op2);
    1178                 :         24 :         dest->is_negative = false;
    1179                 :            :     } else {
    1180                 :         16 :         bigint_rem(dest, op1, op2);
    1181                 :         16 :         dest->is_negative = false;
    1182                 :            :     }
    1183                 :         40 : }
    1184                 :            : 
    1185                 :       3107 : void bigint_or(BigInt *dest, const BigInt *op1, const BigInt *op2) {
    1186         [ +  + ]:       3107 :     if (op1->digit_count == 0) {
    1187                 :        475 :         return bigint_init_bigint(dest, op2);
    1188                 :            :     }
    1189         [ +  + ]:       2632 :     if (op2->digit_count == 0) {
    1190                 :          8 :         return bigint_init_bigint(dest, op1);
    1191                 :            :     }
    1192 [ +  + ][ +  + ]:       2624 :     if (op1->is_negative || op2->is_negative) {
    1193                 :         16 :         size_t big_bit_count = max(bigint_bits_needed(op1), bigint_bits_needed(op2));
    1194                 :            : 
    1195                 :         16 :         BigInt twos_comp_op1 = {0};
    1196                 :         16 :         to_twos_complement(&twos_comp_op1, op1, big_bit_count);
    1197                 :            : 
    1198                 :         16 :         BigInt twos_comp_op2 = {0};
    1199                 :         16 :         to_twos_complement(&twos_comp_op2, op2, big_bit_count);
    1200                 :            : 
    1201                 :         16 :         BigInt twos_comp_dest = {0};
    1202                 :         16 :         bigint_or(&twos_comp_dest, &twos_comp_op1, &twos_comp_op2);
    1203                 :            : 
    1204                 :         16 :         from_twos_complement(dest, &twos_comp_dest, big_bit_count, true);
    1205                 :            :     } else {
    1206                 :       2608 :         dest->is_negative = false;
    1207                 :       2608 :         const uint64_t *op1_digits = bigint_ptr(op1);
    1208                 :       2608 :         const uint64_t *op2_digits = bigint_ptr(op2);
    1209 [ +  + ][ +  + ]:       2608 :         if (op1->digit_count == 1 && op2->digit_count == 1) {
    1210                 :       2584 :             dest->digit_count = 1;
    1211                 :       2584 :             dest->data.digit = op1_digits[0] | op2_digits[0];
    1212                 :       2584 :             bigint_normalize(dest);
    1213                 :       2584 :             return;
    1214                 :            :         }
    1215                 :         24 :         dest->digit_count = max(op1->digit_count, op2->digit_count);
    1216                 :         24 :         dest->data.digits = allocate_nonzero<uint64_t>(dest->digit_count);
    1217         [ +  + ]:         72 :         for (size_t i = 0; i < dest->digit_count; i += 1) {
    1218                 :         48 :             uint64_t digit = 0;
    1219         [ +  + ]:         48 :             if (i < op1->digit_count) {
    1220                 :         40 :                 digit |= op1_digits[i];
    1221                 :            :             }
    1222         [ +  - ]:         48 :             if (i < op2->digit_count) {
    1223                 :         48 :                 digit |= op2_digits[i];
    1224                 :            :             }
    1225                 :         48 :             dest->data.digits[i] = digit;
    1226                 :            :         }
    1227                 :         24 :         bigint_normalize(dest);
    1228                 :            :     }
    1229                 :            : }
    1230                 :            : 
    1231                 :       6280 : void bigint_and(BigInt *dest, const BigInt *op1, const BigInt *op2) {
    1232 [ +  - ][ -  + ]:       6280 :     if (op1->digit_count == 0 || op2->digit_count == 0) {
    1233                 :          0 :         return bigint_init_unsigned(dest, 0);
    1234                 :            :     }
    1235 [ +  + ][ +  + ]:       6280 :     if (op1->is_negative || op2->is_negative) {
    1236                 :         24 :         size_t big_bit_count = max(bigint_bits_needed(op1), bigint_bits_needed(op2));
    1237                 :            : 
    1238                 :         24 :         BigInt twos_comp_op1 = {0};
    1239                 :         24 :         to_twos_complement(&twos_comp_op1, op1, big_bit_count);
    1240                 :            : 
    1241                 :         24 :         BigInt twos_comp_op2 = {0};
    1242                 :         24 :         to_twos_complement(&twos_comp_op2, op2, big_bit_count);
    1243                 :            : 
    1244                 :         24 :         BigInt twos_comp_dest = {0};
    1245                 :         24 :         bigint_and(&twos_comp_dest, &twos_comp_op1, &twos_comp_op2);
    1246                 :            : 
    1247                 :         24 :         from_twos_complement(dest, &twos_comp_dest, big_bit_count, true);
    1248                 :            :     } else {
    1249                 :       6256 :         dest->is_negative = false;
    1250                 :       6256 :         const uint64_t *op1_digits = bigint_ptr(op1);
    1251                 :       6256 :         const uint64_t *op2_digits = bigint_ptr(op2);
    1252 [ +  + ][ +  + ]:       6256 :         if (op1->digit_count == 1 && op2->digit_count == 1) {
    1253                 :       6216 :             dest->digit_count = 1;
    1254                 :       6216 :             dest->data.digit = op1_digits[0] & op2_digits[0];
    1255                 :       6216 :             bigint_normalize(dest);
    1256                 :       6216 :             return;
    1257                 :            :         }
    1258                 :            : 
    1259                 :         40 :         dest->digit_count = max(op1->digit_count, op2->digit_count);
    1260                 :         40 :         dest->data.digits = allocate_nonzero<uint64_t>(dest->digit_count);
    1261                 :            : 
    1262                 :         40 :         size_t i = 0;
    1263 [ +  + ][ +  + ]:         96 :         for (; i < op1->digit_count && i < op2->digit_count; i += 1) {
    1264                 :         56 :             dest->data.digits[i] = op1_digits[i] & op2_digits[i];
    1265                 :            :         }
    1266         [ +  + ]:         64 :         for (; i < dest->digit_count; i += 1) {
    1267                 :         24 :             dest->data.digits[i] = 0;
    1268                 :            :         }
    1269                 :         40 :         bigint_normalize(dest);
    1270                 :            :     }
    1271                 :            : }
    1272                 :            : 
    1273                 :        276 : void bigint_xor(BigInt *dest, const BigInt *op1, const BigInt *op2) {
    1274         [ -  + ]:        276 :     if (op1->digit_count == 0) {
    1275                 :          0 :         return bigint_init_bigint(dest, op2);
    1276                 :            :     }
    1277         [ +  + ]:        276 :     if (op2->digit_count == 0) {
    1278                 :         24 :         return bigint_init_bigint(dest, op1);
    1279                 :            :     }
    1280 [ +  + ][ +  + ]:        252 :     if (op1->is_negative || op2->is_negative) {
    1281                 :         16 :         size_t big_bit_count = max(bigint_bits_needed(op1), bigint_bits_needed(op2));
    1282                 :            : 
    1283                 :         16 :         BigInt twos_comp_op1 = {0};
    1284                 :         16 :         to_twos_complement(&twos_comp_op1, op1, big_bit_count);
    1285                 :            : 
    1286                 :         16 :         BigInt twos_comp_op2 = {0};
    1287                 :         16 :         to_twos_complement(&twos_comp_op2, op2, big_bit_count);
    1288                 :            : 
    1289                 :         16 :         BigInt twos_comp_dest = {0};
    1290                 :         16 :         bigint_xor(&twos_comp_dest, &twos_comp_op1, &twos_comp_op2);
    1291                 :            : 
    1292                 :         16 :         from_twos_complement(dest, &twos_comp_dest, big_bit_count, true);
    1293                 :            :     } else {
    1294                 :        236 :         dest->is_negative = false;
    1295                 :        236 :         const uint64_t *op1_digits = bigint_ptr(op1);
    1296                 :        236 :         const uint64_t *op2_digits = bigint_ptr(op2);
    1297                 :            : 
    1298 [ +  - ][ +  - ]:        236 :         assert(op1->digit_count > 0 && op2->digit_count > 0);
    1299 [ +  + ][ +  + ]:        236 :         if (op1->digit_count == 1 && op2->digit_count == 1) {
    1300                 :        152 :             dest->digit_count = 1;
    1301                 :        152 :             dest->data.digit = op1_digits[0] ^ op2_digits[0];
    1302                 :        152 :             bigint_normalize(dest);
    1303                 :        152 :             return;
    1304                 :            :         }
    1305                 :         84 :         dest->digit_count = max(op1->digit_count, op2->digit_count);
    1306                 :         84 :         dest->data.digits = allocate_nonzero<uint64_t>(dest->digit_count);
    1307                 :         84 :         size_t i = 0;
    1308 [ +  + ][ +  + ]:        228 :         for (; i < op1->digit_count && i < op2->digit_count; i += 1) {
    1309                 :        144 :             dest->data.digits[i] = op1_digits[i] ^ op2_digits[i];
    1310                 :            :         }
    1311         [ +  + ]:        108 :         for (; i < dest->digit_count; i += 1) {
    1312         [ +  + ]:         24 :             if (i < op1->digit_count) {
    1313                 :          8 :                 dest->data.digits[i] = op1_digits[i];
    1314         [ +  - ]:         16 :             } else if (i < op2->digit_count) {
    1315                 :         16 :                 dest->data.digits[i] = op2_digits[i];
    1316                 :            :             } else {
    1317                 :          0 :                 zig_unreachable();
    1318                 :            :             }
    1319                 :            :         }
    1320                 :         84 :         bigint_normalize(dest);
    1321                 :            :     }
    1322                 :            : }
    1323                 :            : 
    1324                 :     161624 : void bigint_shl(BigInt *dest, const BigInt *op1, const BigInt *op2) {
    1325                 :     161624 :     assert(!op2->is_negative);
    1326                 :            : 
    1327         [ +  + ]:     161624 :     if (op2->digit_count == 0) {
    1328                 :        525 :         bigint_init_bigint(dest, op1);
    1329                 :        525 :         return;
    1330                 :            :     }
    1331                 :            : 
    1332         [ +  + ]:     161099 :     if (op1->digit_count == 0) {
    1333                 :      59889 :         bigint_init_unsigned(dest, 0);
    1334                 :      59889 :         return;
    1335                 :            :     }
    1336                 :            : 
    1337         [ -  + ]:     101210 :     if (op2->digit_count != 1) {
    1338                 :          0 :         zig_panic("TODO shift left by amount greater than 64 bit integer");
    1339                 :            :     }
    1340                 :            : 
    1341                 :     101210 :     const uint64_t *op1_digits = bigint_ptr(op1);
    1342                 :     101210 :     uint64_t shift_amt = bigint_as_unsigned(op2);
    1343                 :            : 
    1344 [ +  + ][ +  + ]:     101210 :     if (op1->digit_count == 1 && shift_amt < 64) {
    1345                 :      57156 :         dest->data.digit = op1_digits[0] << shift_amt;
    1346         [ +  + ]:      57156 :         if (dest->data.digit > op1_digits[0]) {
    1347                 :      57144 :             dest->digit_count = 1;
    1348                 :      57144 :             dest->is_negative = op1->is_negative;
    1349                 :      57144 :             return;
    1350                 :            :         }
    1351                 :            :     }
    1352                 :            : 
    1353                 :      44066 :     uint64_t digit_shift_count = shift_amt / 64;
    1354                 :      44066 :     uint64_t leftover_shift_count = shift_amt % 64;
    1355                 :            : 
    1356                 :      44066 :     dest->data.digits = allocate<uint64_t>(op1->digit_count + digit_shift_count + 1);
    1357                 :      44066 :     dest->digit_count = digit_shift_count;
    1358                 :      44066 :     uint64_t carry = 0;
    1359         [ +  + ]:      95714 :     for (size_t i = 0; i < op1->digit_count; i += 1) {
    1360                 :      51648 :         uint64_t digit = op1_digits[i];
    1361                 :      51648 :         dest->data.digits[dest->digit_count] = carry | (digit << leftover_shift_count);
    1362                 :      51648 :         dest->digit_count += 1;
    1363         [ +  + ]:      51648 :         if (leftover_shift_count > 0) {
    1364                 :        492 :             carry = digit >> (64 - leftover_shift_count);
    1365                 :            :         } else {
    1366                 :      51156 :             carry = 0;
    1367                 :            :         }
    1368                 :            :     }
    1369                 :      44066 :     dest->data.digits[dest->digit_count] = carry;
    1370                 :      44066 :     dest->digit_count += 1;
    1371                 :      44066 :     dest->is_negative = op1->is_negative;
    1372                 :      44066 :     bigint_normalize(dest);
    1373                 :            : }
    1374                 :            : 
    1375                 :       4564 : void bigint_shl_trunc(BigInt *dest, const BigInt *op1, const BigInt *op2, size_t bit_count, bool is_signed) {
    1376                 :       4564 :     BigInt unwrapped = {0};
    1377                 :       4564 :     bigint_shl(&unwrapped, op1, op2);
    1378                 :       4564 :     bigint_truncate(dest, &unwrapped, bit_count, is_signed);
    1379                 :       4564 : }
    1380                 :            : 
    1381                 :      10927 : void bigint_shr(BigInt *dest, const BigInt *op1, const BigInt *op2) {
    1382                 :      10927 :     assert(!op2->is_negative);
    1383                 :            : 
    1384         [ +  + ]:      10927 :     if (op1->digit_count == 0) {
    1385                 :          8 :         return bigint_init_unsigned(dest, 0);
    1386                 :            :     }
    1387                 :            : 
    1388         [ -  + ]:      10919 :     if (op2->digit_count == 0) {
    1389                 :          0 :         return bigint_init_bigint(dest, op1);
    1390                 :            :     }
    1391                 :            : 
    1392         [ -  + ]:      10919 :     if (op2->digit_count != 1) {
    1393                 :          0 :         zig_panic("TODO shift right by amount greater than 64 bit integer");
    1394                 :            :     }
    1395                 :            : 
    1396                 :      10919 :     const uint64_t *op1_digits = bigint_ptr(op1);
    1397                 :      10919 :     uint64_t shift_amt = bigint_as_unsigned(op2);
    1398                 :            : 
    1399         [ +  + ]:      10919 :     if (op1->digit_count == 1) {
    1400         [ +  + ]:      10871 :         dest->data.digit = (shift_amt < 64) ? op1_digits[0] >> shift_amt : 0;
    1401                 :      10871 :         dest->digit_count = 1;
    1402                 :      10871 :         dest->is_negative = op1->is_negative;
    1403                 :      10871 :         bigint_normalize(dest);
    1404                 :      10871 :         return;
    1405                 :            :     }
    1406                 :            : 
    1407                 :         48 :     size_t digit_shift_count = shift_amt / 64;
    1408                 :         48 :     size_t leftover_shift_count = shift_amt % 64;
    1409                 :            : 
    1410         [ -  + ]:         48 :     if (digit_shift_count >= op1->digit_count) {
    1411                 :          0 :         return bigint_init_unsigned(dest, 0);
    1412                 :            :     }
    1413                 :            : 
    1414                 :         48 :     dest->digit_count = op1->digit_count - digit_shift_count;
    1415                 :            :     uint64_t *digits;
    1416         [ +  + ]:         48 :     if (dest->digit_count == 1) {
    1417                 :         16 :         digits = &dest->data.digit;
    1418                 :            :     } else {
    1419                 :         32 :         digits = allocate<uint64_t>(dest->digit_count);
    1420                 :         32 :         dest->data.digits = digits;
    1421                 :            :     }
    1422                 :            : 
    1423                 :         48 :     uint64_t carry = 0;
    1424                 :         48 :     for (size_t op_digit_index = op1->digit_count - 1;;) {
    1425                 :         80 :         uint64_t digit = op1_digits[op_digit_index];
    1426                 :         80 :         size_t dest_digit_index = op_digit_index - digit_shift_count;
    1427                 :         80 :         digits[dest_digit_index] = carry | (digit >> leftover_shift_count);
    1428                 :         80 :         carry = digit << (64 - leftover_shift_count);
    1429                 :            : 
    1430         [ +  + ]:         80 :         if (dest_digit_index == 0) { break; }
    1431                 :         32 :         op_digit_index -= 1;
    1432                 :         32 :     }
    1433                 :         48 :     dest->is_negative = op1->is_negative;
    1434                 :         48 :     bigint_normalize(dest);
    1435                 :            : }
    1436                 :            : 
    1437                 :     184422 : void bigint_negate(BigInt *dest, const BigInt *op) {
    1438                 :     184422 :     bigint_init_bigint(dest, op);
    1439                 :     184422 :     dest->is_negative = !dest->is_negative;
    1440                 :     184422 :     bigint_normalize(dest);
    1441                 :     184422 : }
    1442                 :            : 
    1443                 :         40 : void bigint_negate_wrap(BigInt *dest, const BigInt *op, size_t bit_count) {
    1444                 :            :     BigInt zero;
    1445                 :         40 :     bigint_init_unsigned(&zero, 0);
    1446                 :         40 :     bigint_sub_wrap(dest, &zero, op, bit_count, true);
    1447                 :         40 : }
    1448                 :            : 
    1449                 :       1074 : void bigint_not(BigInt *dest, const BigInt *op, size_t bit_count, bool is_signed) {
    1450         [ -  + ]:       1074 :     if (bit_count == 0) {
    1451                 :          0 :         bigint_init_unsigned(dest, 0);
    1452                 :          0 :         return;
    1453                 :            :     }
    1454                 :            : 
    1455         [ +  + ]:       1074 :     if (is_signed) {
    1456                 :         26 :         BigInt twos_comp = {0};
    1457                 :         26 :         to_twos_complement(&twos_comp, op, bit_count);
    1458                 :            : 
    1459                 :         26 :         BigInt inverted = {0};
    1460                 :         26 :         bigint_not(&inverted, &twos_comp, bit_count, false);
    1461                 :            : 
    1462                 :         26 :         from_twos_complement(dest, &inverted, bit_count, true);
    1463                 :         26 :         return;
    1464                 :            :     }
    1465                 :            : 
    1466                 :       1048 :     assert(!op->is_negative);
    1467                 :            : 
    1468                 :       1048 :     dest->is_negative = false;
    1469                 :       1048 :     const uint64_t *op_digits = bigint_ptr(op);
    1470         [ +  + ]:       1048 :     if (bit_count <= 64) {
    1471                 :        772 :         dest->digit_count = 1;
    1472         [ +  + ]:        772 :         if (op->digit_count == 0) {
    1473         [ +  + ]:         48 :             if (bit_count == 64) {
    1474                 :         32 :                 dest->data.digit = UINT64_MAX;
    1475                 :            :             } else {
    1476                 :         48 :                 dest->data.digit = (1ULL << bit_count) - 1;
    1477                 :            :             }
    1478         [ +  - ]:        724 :         } else if (op->digit_count == 1) {
    1479                 :        724 :             dest->data.digit = ~op_digits[0];
    1480         [ +  + ]:        724 :             if (bit_count != 64) {
    1481                 :        570 :                 uint64_t mask = (1ULL << bit_count) - 1;
    1482                 :        724 :                 dest->data.digit &= mask;
    1483                 :            :             }
    1484                 :            :         }
    1485                 :        772 :         bigint_normalize(dest);
    1486                 :        772 :         return;
    1487                 :            :     }
    1488                 :        276 :     dest->digit_count = (bit_count + 63) / 64;
    1489                 :        276 :     assert(dest->digit_count >= op->digit_count);
    1490                 :        276 :     dest->data.digits = allocate_nonzero<uint64_t>(dest->digit_count);
    1491                 :        276 :     size_t i = 0;
    1492         [ +  + ]:        692 :     for (; i < op->digit_count; i += 1) {
    1493                 :        416 :         dest->data.digits[i] = ~op_digits[i];
    1494                 :            :     }
    1495         [ +  + ]:        412 :     for (; i < dest->digit_count; i += 1) {
    1496                 :        136 :         dest->data.digits[i] = 0xffffffffffffffffULL;
    1497                 :            :     }
    1498                 :        276 :     size_t digit_index = dest->digit_count - 1;
    1499                 :        276 :     size_t digit_bit_index = bit_count % 64;
    1500         [ +  + ]:        276 :     if (digit_bit_index != 0) {
    1501                 :        128 :         uint64_t mask = (1ULL << digit_bit_index) - 1;
    1502                 :        128 :         dest->data.digits[digit_index] &= mask;
    1503                 :            :     }
    1504                 :        276 :     bigint_normalize(dest);
    1505                 :            : }
    1506                 :            : 
    1507                 :       6932 : void bigint_truncate(BigInt *dest, const BigInt *op, size_t bit_count, bool is_signed) {
    1508                 :            :     BigInt twos_comp;
    1509                 :       6932 :     to_twos_complement(&twos_comp, op, bit_count);
    1510                 :       6932 :     from_twos_complement(dest, &twos_comp, bit_count, is_signed);
    1511                 :       6932 : }
    1512                 :            : 
    1513                 :     772066 : Cmp bigint_cmp(const BigInt *op1, const BigInt *op2) {
    1514 [ +  + ][ +  + ]:     772066 :     if (op1->is_negative && !op2->is_negative) {
    1515                 :      14050 :         return CmpLT;
    1516 [ +  + ][ +  + ]:     758016 :     } else if (!op1->is_negative && op2->is_negative) {
    1517                 :      39260 :         return CmpGT;
    1518         [ +  + ]:     718756 :     } else if (op1->digit_count > op2->digit_count) {
    1519         [ -  + ]:      19115 :         return op1->is_negative ? CmpLT : CmpGT;
    1520         [ +  + ]:     699641 :     } else if (op2->digit_count > op1->digit_count) {
    1521         [ +  + ]:       3282 :         return op1->is_negative ? CmpGT : CmpLT;
    1522         [ +  + ]:     696359 :     } else if (op1->digit_count == 0) {
    1523                 :      37875 :         return CmpEQ;
    1524                 :            :     }
    1525                 :     658484 :     const uint64_t *op1_digits = bigint_ptr(op1);
    1526                 :     658484 :     const uint64_t *op2_digits = bigint_ptr(op2);
    1527                 :     658484 :     for (size_t i = op1->digit_count - 1; ;) {
    1528                 :     658972 :         uint64_t op1_digit = op1_digits[i];
    1529                 :     658972 :         uint64_t op2_digit = op2_digits[i];
    1530                 :            : 
    1531         [ +  + ]:     658972 :         if (op1_digit > op2_digit) {
    1532         [ +  + ]:     272291 :             return op1->is_negative ? CmpLT : CmpGT;
    1533                 :            :         }
    1534         [ +  + ]:     386681 :         if (op1_digit < op2_digit) {
    1535         [ +  + ]:     166996 :             return op1->is_negative ? CmpGT : CmpLT;
    1536                 :            :         }
    1537                 :            : 
    1538         [ +  + ]:     219685 :         if (i == 0) {
    1539                 :     219197 :             return CmpEQ;
    1540                 :            :         }
    1541                 :        488 :         i -= 1;
    1542                 :        488 :     }
    1543                 :            : }
    1544                 :            : 
    1545                 :         88 : void bigint_append_buf(Buf *buf, const BigInt *op, uint64_t base) {
    1546         [ +  + ]:         88 :     if (op->digit_count == 0) {
    1547                 :         24 :         buf_append_char(buf, '0');
    1548                 :         88 :         return;
    1549                 :            :     }
    1550         [ -  + ]:         64 :     if (op->is_negative) {
    1551                 :          0 :         buf_append_char(buf, '-');
    1552                 :            :     }
    1553 [ +  - ][ +  - ]:         64 :     if (op->digit_count == 1 && base == 10) {
    1554                 :         64 :         buf_appendf(buf, "%" ZIG_PRI_u64, op->data.digit);
    1555                 :         64 :         return;
    1556                 :            :     }
    1557 [ #  # ][ #  # ]:          0 :     if (op->digit_count == 1 && base == 16) {
    1558                 :          0 :         buf_appendf(buf, "%" ZIG_PRI_x64, op->data.digit);
    1559                 :          0 :         return;
    1560                 :            :     }
    1561                 :          0 :     size_t first_digit_index = buf_len(buf);
    1562                 :            : 
    1563                 :          0 :     BigInt digit_bi = {0};
    1564                 :          0 :     BigInt a1 = {0};
    1565                 :          0 :     BigInt a2 = {0};
    1566                 :            : 
    1567                 :          0 :     BigInt *a = &a1;
    1568                 :          0 :     BigInt *other_a = &a2;
    1569                 :          0 :     bigint_init_bigint(a, op);
    1570                 :            : 
    1571                 :          0 :     BigInt base_bi = {0};
    1572                 :          0 :     bigint_init_unsigned(&base_bi, base);
    1573                 :            : 
    1574                 :            :     for (;;) {
    1575                 :          0 :         bigint_rem(&digit_bi, a, &base_bi);
    1576                 :          0 :         uint8_t digit = bigint_as_unsigned(&digit_bi);
    1577                 :          0 :         buf_append_char(buf, digit_to_char(digit, false));
    1578                 :          0 :         bigint_div_trunc(other_a, a, &base_bi);
    1579                 :            :         {
    1580                 :          0 :             BigInt *tmp = a;
    1581                 :          0 :             a = other_a;
    1582                 :          0 :             other_a = tmp;
    1583                 :            :         }
    1584         [ #  # ]:          0 :         if (bigint_cmp_zero(a) == CmpEQ) {
    1585                 :          0 :             break;
    1586                 :            :         }
    1587                 :          0 :     }
    1588                 :            : 
    1589                 :            :     // reverse
    1590         [ #  # ]:          0 :     for (size_t i = first_digit_index; i < buf_len(buf) / 2; i += 1) {
    1591                 :          0 :         size_t other_i = buf_len(buf) + first_digit_index - i - 1;
    1592                 :          0 :         uint8_t tmp = buf_ptr(buf)[i];
    1593                 :          0 :         buf_ptr(buf)[i] = buf_ptr(buf)[other_i];
    1594                 :          0 :         buf_ptr(buf)[other_i] = tmp;
    1595                 :            :     }
    1596                 :            : }
    1597                 :            : 
    1598                 :        538 : size_t bigint_popcount_unsigned(const BigInt *bi) {
    1599                 :        538 :     assert(!bi->is_negative);
    1600         [ +  + ]:        538 :     if (bi->digit_count == 0)
    1601                 :         61 :         return 0;
    1602                 :            : 
    1603                 :        477 :     size_t count = 0;
    1604                 :        477 :     size_t bit_count = bi->digit_count * 64;
    1605         [ +  + ]:      31005 :     for (size_t i = 0; i < bit_count; i += 1) {
    1606         [ +  + ]:      30528 :         if (bit_at_index(bi, i))
    1607                 :       1779 :             count += 1;
    1608                 :            :     }
    1609                 :        477 :     return count;
    1610                 :            : }
    1611                 :            : 
    1612                 :         16 : size_t bigint_popcount_signed(const BigInt *bi, size_t bit_count) {
    1613         [ -  + ]:         16 :     if (bit_count == 0)
    1614                 :          0 :         return 0;
    1615         [ -  + ]:         16 :     if (bi->digit_count == 0)
    1616                 :          0 :         return 0;
    1617                 :            : 
    1618                 :         16 :     BigInt twos_comp = {0};
    1619                 :         16 :     to_twos_complement(&twos_comp, bi, bit_count);
    1620                 :            : 
    1621                 :         16 :     size_t count = 0;
    1622         [ +  + ]:        208 :     for (size_t i = 0; i < bit_count; i += 1) {
    1623         [ +  + ]:        192 :         if (bit_at_index(&twos_comp, i))
    1624                 :        144 :             count += 1;
    1625                 :            :     }
    1626                 :         16 :     return count;
    1627                 :            : }
    1628                 :            : 
    1629                 :         48 : size_t bigint_ctz(const BigInt *bi, size_t bit_count) {
    1630         [ -  + ]:         48 :     if (bit_count == 0)
    1631                 :          0 :         return 0;
    1632         [ +  + ]:         48 :     if (bi->digit_count == 0)
    1633                 :         16 :         return bit_count;
    1634                 :            : 
    1635                 :         32 :     BigInt twos_comp = {0};
    1636                 :         32 :     to_twos_complement(&twos_comp, bi, bit_count);
    1637                 :            : 
    1638                 :         32 :     size_t count = 0;
    1639         [ +  - ]:       2104 :     for (size_t i = 0; i < bit_count; i += 1) {
    1640         [ +  + ]:       2104 :         if (bit_at_index(&twos_comp, i))
    1641                 :         32 :             return count;
    1642                 :       2072 :         count += 1;
    1643                 :            :     }
    1644                 :         48 :     return count;
    1645                 :            : }
    1646                 :            : 
    1647                 :     362763 : size_t bigint_clz(const BigInt *bi, size_t bit_count) {
    1648 [ +  + ][ +  + ]:     362763 :     if (bi->is_negative || bit_count == 0)
    1649                 :        153 :         return 0;
    1650         [ +  + ]:     362610 :     if (bi->digit_count == 0)
    1651                 :          8 :         return bit_count;
    1652                 :            : 
    1653                 :     362602 :     size_t count = 0;
    1654                 :     362602 :     for (size_t i = bit_count - 1;;) {
    1655         [ +  + ]:   19321480 :         if (bit_at_index(bi, i))
    1656                 :     362602 :             return count;
    1657                 :   18958878 :         count += 1;
    1658                 :            : 
    1659         [ -  + ]:   18958878 :         if (i == 0) break;
    1660                 :   18958878 :         i -= 1;
    1661                 :            :     }
    1662                 :          0 :     return count;
    1663                 :            : }
    1664                 :            : 
    1665                 :     221326 : static uint64_t bigint_as_unsigned(const BigInt *bigint) {
    1666                 :     221326 :     assert(!bigint->is_negative);
    1667         [ +  + ]:     221326 :     if (bigint->digit_count == 0) {
    1668                 :      13381 :         return 0;
    1669         [ +  - ]:     207945 :     } else if (bigint->digit_count == 1) {
    1670                 :     207945 :         return bigint->data.digit;
    1671                 :            :     } else {
    1672                 :          0 :         zig_unreachable();
    1673                 :            :     }
    1674                 :            : }
    1675                 :            : 
    1676                 :     101536 : uint64_t bigint_as_u64(const BigInt *bigint)
    1677                 :            : {
    1678                 :     101536 :     return bigint_as_unsigned(bigint);
    1679                 :            : }
    1680                 :            : 
    1681                 :       4637 : uint32_t bigint_as_u32(const BigInt *bigint) {
    1682                 :       4637 :     uint64_t value64 = bigint_as_unsigned(bigint);
    1683                 :       4637 :     uint32_t value32 = (uint32_t)value64;
    1684                 :       4637 :     assert (value64 == value32);
    1685                 :       4637 :     return value32;
    1686                 :            : }
    1687                 :            : 
    1688                 :       3024 : size_t bigint_as_usize(const BigInt *bigint) {
    1689                 :       3024 :     uint64_t value64 = bigint_as_unsigned(bigint);
    1690                 :       3024 :     size_t valueUsize = (size_t)value64;
    1691                 :       3024 :     assert (value64 == valueUsize);
    1692                 :       3024 :     return valueUsize;
    1693                 :            : }
    1694                 :            : 
    1695                 :       3429 : int64_t bigint_as_signed(const BigInt *bigint) {
    1696         [ +  + ]:       3429 :     if (bigint->digit_count == 0) {
    1697                 :        547 :         return 0;
    1698         [ +  - ]:       2882 :     } else if (bigint->digit_count == 1) {
    1699         [ +  + ]:       2882 :         if (bigint->is_negative) {
    1700         [ +  - ]:          8 :             if (bigint->data.digit <= 9223372036854775808ULL) {
    1701                 :          8 :                 return (-((int64_t)(bigint->data.digit - 1))) - 1;
    1702                 :            :             } else {
    1703                 :          0 :                 zig_unreachable();
    1704                 :            :             }
    1705                 :            :         } else {
    1706                 :       2874 :             return bigint->data.digit;
    1707                 :            :         }
    1708                 :            :     } else {
    1709                 :          0 :         zig_unreachable();
    1710                 :            :     }
    1711                 :            : }
    1712                 :            : 
    1713                 :     342808 : Cmp bigint_cmp_zero(const BigInt *op) {
    1714         [ +  + ]:     342808 :     if (op->digit_count == 0) {
    1715                 :      18796 :         return CmpEQ;
    1716                 :            :     }
    1717         [ +  + ]:     324012 :     return op->is_negative ? CmpLT : CmpGT;
    1718                 :            : }
    1719                 :            : 
    1720                 :     406035 : uint32_t bigint_hash(BigInt x) {
    1721         [ +  + ]:     406035 :     if (x.digit_count == 0) {
    1722                 :      53695 :         return 0;
    1723                 :            :     } else {
    1724                 :     352340 :         return bigint_ptr(&x)[0];
    1725                 :            :     }
    1726                 :            : }
    1727                 :            : 
    1728                 :      90929 : bool bigint_eql(BigInt a, BigInt b) {
    1729                 :      90929 :     return bigint_cmp(&a, &b) == CmpEQ;
    1730                 :            : }
    1731                 :            : 
    1732                 :     113751 : void bigint_incr(BigInt *x) {
    1733         [ +  + ]:     113751 :     if (x->digit_count == 0) {
    1734                 :      12709 :         bigint_init_unsigned(x, 1);
    1735                 :     113751 :         return;
    1736                 :            :     }
    1737                 :            : 
    1738         [ +  - ]:     101042 :     if (x->digit_count == 1) {
    1739 [ +  + ][ +  - ]:     101042 :         if (x->is_negative && x->data.digit != 0) {
    1740                 :          8 :             x->data.digit -= 1;
    1741                 :          8 :             return;
    1742 [ +  - ][ +  - ]:     101034 :         } else if (!x->is_negative && x->data.digit != UINT64_MAX) {
    1743                 :     101034 :             x->data.digit += 1;
    1744                 :     101034 :             return;
    1745                 :            :         }
    1746                 :            :     }
    1747                 :            : 
    1748                 :            :     BigInt copy;
    1749                 :          0 :     bigint_init_bigint(&copy, x);
    1750                 :            : 
    1751                 :            :     BigInt one;
    1752                 :          0 :     bigint_init_unsigned(&one, 1);
    1753                 :            : 
    1754                 :          0 :     bigint_add(x, &copy, &one);
    1755                 :            : }
    1756                 :            : 

Generated by: LCOV version 1.14