quickjs-tart

quickjs-based runtime for wallet-core logic
Log | Files | Refs | README | LICENSE

ares_math.c (4034B)


      1 /* MIT License
      2  *
      3  * Copyright (c) 2023 Brad House
      4  *
      5  * Permission is hereby granted, free of charge, to any person obtaining a copy
      6  * of this software and associated documentation files (the "Software"), to deal
      7  * in the Software without restriction, including without limitation the rights
      8  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
      9  * copies of the Software, and to permit persons to whom the Software is
     10  * furnished to do so, subject to the following conditions:
     11  *
     12  * The above copyright notice and this permission notice (including the next
     13  * paragraph) shall be included in all copies or substantial portions of the
     14  * Software.
     15  *
     16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
     19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
     22  * SOFTWARE.
     23  *
     24  * SPDX-License-Identifier: MIT
     25  */
     26 
     27 #include "ares_private.h"
     28 
     29 /* Uses public domain code snippets from
     30  * http://graphics.stanford.edu/~seander/bithacks.html */
     31 
     32 static unsigned int ares_round_up_pow2_u32(unsigned int n)
     33 {
     34   /* NOTE: if already a power of 2, will return itself, not the next */
     35   n--;
     36   n |= n >> 1;
     37   n |= n >> 2;
     38   n |= n >> 4;
     39   n |= n >> 8;
     40   n |= n >> 16;
     41   n++;
     42   return n;
     43 }
     44 
     45 static ares_int64_t ares_round_up_pow2_u64(ares_int64_t n)
     46 {
     47   /* NOTE: if already a power of 2, will return itself, not the next */
     48   n--;
     49   n |= n >> 1;
     50   n |= n >> 2;
     51   n |= n >> 4;
     52   n |= n >> 8;
     53   n |= n >> 16;
     54   n |= n >> 32;
     55   n++;
     56   return n;
     57 }
     58 
     59 ares_bool_t ares_is_64bit(void)
     60 {
     61 #ifdef _MSC_VER
     62 #  pragma warning(push)
     63 #  pragma warning(disable : 4127)
     64 #endif
     65 
     66   return (sizeof(size_t) == 4) ? ARES_FALSE : ARES_TRUE;
     67 
     68 #ifdef _MSC_VER
     69 #  pragma warning(pop)
     70 #endif
     71 }
     72 
     73 size_t ares_round_up_pow2(size_t n)
     74 {
     75   if (ares_is_64bit()) {
     76     return (size_t)ares_round_up_pow2_u64((ares_int64_t)n);
     77   }
     78 
     79   return (size_t)ares_round_up_pow2_u32((unsigned int)n);
     80 }
     81 
     82 size_t ares_log2(size_t n)
     83 {
     84   static const unsigned char tab32[32] = { 0,  1,  28, 2,  29, 14, 24, 3,
     85                                            30, 22, 20, 15, 25, 17, 4,  8,
     86                                            31, 27, 13, 23, 21, 19, 16, 7,
     87                                            26, 12, 18, 6,  11, 5,  10, 9 };
     88   static const unsigned char tab64[64] = {
     89     63, 0,  58, 1,  59, 47, 53, 2,  60, 39, 48, 27, 54, 33, 42, 3,
     90     61, 51, 37, 40, 49, 18, 28, 20, 55, 30, 34, 11, 43, 14, 22, 4,
     91     62, 57, 46, 52, 38, 26, 32, 41, 50, 36, 17, 19, 29, 10, 13, 21,
     92     56, 45, 25, 31, 35, 16, 9,  12, 44, 24, 15, 8,  23, 7,  6,  5
     93   };
     94 
     95   if (!ares_is_64bit()) {
     96     return tab32[(n * 0x077CB531) >> 27];
     97   }
     98 
     99   return tab64[(n * 0x07EDD5E59A4E28C2) >> 58];
    100 }
    101 
    102 /* x^y */
    103 size_t ares_pow(size_t x, size_t y)
    104 {
    105   size_t res = 1;
    106 
    107   while (y > 0) {
    108     /* If y is odd, multiply x with result */
    109     if (y & 1) {
    110       res = res * x;
    111     }
    112 
    113     /* y must be even now */
    114     y = y >> 1; /* y /= 2; */
    115     x = x * x;  /* x^2 */
    116   }
    117 
    118   return res;
    119 }
    120 
    121 size_t ares_count_digits(size_t n)
    122 {
    123   size_t digits;
    124 
    125   for (digits = 0; n > 0; digits++) {
    126     n /= 10;
    127   }
    128   if (digits == 0) {
    129     digits = 1;
    130   }
    131 
    132   return digits;
    133 }
    134 
    135 size_t ares_count_hexdigits(size_t n)
    136 {
    137   size_t digits;
    138 
    139   for (digits = 0; n > 0; digits++) {
    140     n /= 16;
    141   }
    142   if (digits == 0) {
    143     digits = 1;
    144   }
    145 
    146   return digits;
    147 }
    148 
    149 unsigned char ares_count_bits_u8(unsigned char x)
    150 {
    151   /* Implementation obtained from:
    152    * http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetTable */
    153 #define B2(n) n, n + 1, n + 1, n + 2
    154 #define B4(n) B2(n), B2(n + 1), B2(n + 1), B2(n + 2)
    155 #define B6(n) B4(n), B4(n + 1), B4(n + 1), B4(n + 2)
    156   static const unsigned char lookup[256] = { B6(0), B6(1), B6(1), B6(2) };
    157   return lookup[x];
    158 }