Coverage Report

Created: 2026-01-10 06:09

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/c-ares/src/lib/util/ares_math.c
Line
Count
Source
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
0
{
34
  /* NOTE: if already a power of 2, will return itself, not the next */
35
0
  n--;
36
0
  n |= n >> 1;
37
0
  n |= n >> 2;
38
0
  n |= n >> 4;
39
0
  n |= n >> 8;
40
0
  n |= n >> 16;
41
0
  n++;
42
0
  return n;
43
0
}
44
45
static ares_int64_t ares_round_up_pow2_u64(ares_int64_t n)
46
15.9M
{
47
  /* NOTE: if already a power of 2, will return itself, not the next */
48
15.9M
  n--;
49
15.9M
  n |= n >> 1;
50
15.9M
  n |= n >> 2;
51
15.9M
  n |= n >> 4;
52
15.9M
  n |= n >> 8;
53
15.9M
  n |= n >> 16;
54
15.9M
  n |= n >> 32;
55
15.9M
  n++;
56
15.9M
  return n;
57
15.9M
}
58
59
ares_bool_t ares_is_64bit(void)
60
15.9M
{
61
#ifdef _MSC_VER
62
#  pragma warning(push)
63
#  pragma warning(disable : 4127)
64
#endif
65
66
15.9M
  return (sizeof(size_t) == 4) ? ARES_FALSE : ARES_TRUE;
67
68
#ifdef _MSC_VER
69
#  pragma warning(pop)
70
#endif
71
15.9M
}
72
73
size_t ares_round_up_pow2(size_t n)
74
15.9M
{
75
15.9M
  if (ares_is_64bit()) {
76
15.9M
    return (size_t)ares_round_up_pow2_u64((ares_int64_t)n);
77
15.9M
  }
78
79
0
  return (size_t)ares_round_up_pow2_u32((unsigned int)n);
80
15.9M
}
81
82
size_t ares_log2(size_t n)
83
13.2k
{
84
13.2k
  static const unsigned char tab32[32] = { 0,  1,  28, 2,  29, 14, 24, 3,
85
13.2k
                                           30, 22, 20, 15, 25, 17, 4,  8,
86
13.2k
                                           31, 27, 13, 23, 21, 19, 16, 7,
87
13.2k
                                           26, 12, 18, 6,  11, 5,  10, 9 };
88
13.2k
  static const unsigned char tab64[64] = {
89
13.2k
    63, 0,  58, 1,  59, 47, 53, 2,  60, 39, 48, 27, 54, 33, 42, 3,
90
13.2k
    61, 51, 37, 40, 49, 18, 28, 20, 55, 30, 34, 11, 43, 14, 22, 4,
91
13.2k
    62, 57, 46, 52, 38, 26, 32, 41, 50, 36, 17, 19, 29, 10, 13, 21,
92
13.2k
    56, 45, 25, 31, 35, 16, 9,  12, 44, 24, 15, 8,  23, 7,  6,  5
93
13.2k
  };
94
95
13.2k
  if (!ares_is_64bit()) {
96
0
    return tab32[(n * 0x077CB531) >> 27];
97
0
  }
98
99
13.2k
  return tab64[(n * 0x07EDD5E59A4E28C2) >> 58];
100
13.2k
}
101
102
/* x^y */
103
size_t ares_pow(size_t x, size_t y)
104
112k
{
105
112k
  size_t res = 1;
106
107
337k
  while (y > 0) {
108
    /* If y is odd, multiply x with result */
109
225k
    if (y & 1) {
110
154k
      res = res * x;
111
154k
    }
112
113
    /* y must be even now */
114
225k
    y = y >> 1; /* y /= 2; */
115
225k
    x = x * x;  /* x^2 */
116
225k
  }
117
118
112k
  return res;
119
112k
}
120
121
size_t ares_count_digits(size_t n)
122
112k
{
123
112k
  size_t digits;
124
125
456k
  for (digits = 0; n > 0; digits++) {
126
344k
    n /= 10;
127
344k
  }
128
112k
  if (digits == 0) {
129
52.2k
    digits = 1;
130
52.2k
  }
131
132
112k
  return digits;
133
112k
}
134
135
size_t ares_count_hexdigits(size_t n)
136
1.85k
{
137
1.85k
  size_t digits;
138
139
4.48k
  for (digits = 0; n > 0; digits++) {
140
2.62k
    n /= 16;
141
2.62k
  }
142
1.85k
  if (digits == 0) {
143
382
    digits = 1;
144
382
  }
145
146
1.85k
  return digits;
147
1.85k
}
148
149
unsigned char ares_count_bits_u8(unsigned char x)
150
0
{
151
  /* Implementation obtained from:
152
   * http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetTable */
153
0
#define B2(n) n, n + 1, n + 1, n + 2
154
0
#define B4(n) B2(n), B2(n + 1), B2(n + 1), B2(n + 2)
155
0
#define B6(n) B4(n), B4(n + 1), B4(n + 1), B4(n + 2)
156
0
  static const unsigned char lookup[256] = { B6(0), B6(1), B6(1), B6(2) };
157
0
  return lookup[x];
158
0
}