mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-12-06 19:41:15 +01:00
Extract simple integer math into its own module
This commit is contained in:
@@ -166,105 +166,6 @@ tor_llround(double d)
|
||||
#endif /* defined(HAVE_LLROUND) || ... */
|
||||
}
|
||||
|
||||
/** Returns floor(log2(u64)). If u64 is 0, (incorrectly) returns 0. */
|
||||
int
|
||||
tor_log2(uint64_t u64)
|
||||
{
|
||||
int r = 0;
|
||||
if (u64 >= (U64_LITERAL(1)<<32)) {
|
||||
u64 >>= 32;
|
||||
r = 32;
|
||||
}
|
||||
if (u64 >= (U64_LITERAL(1)<<16)) {
|
||||
u64 >>= 16;
|
||||
r += 16;
|
||||
}
|
||||
if (u64 >= (U64_LITERAL(1)<<8)) {
|
||||
u64 >>= 8;
|
||||
r += 8;
|
||||
}
|
||||
if (u64 >= (U64_LITERAL(1)<<4)) {
|
||||
u64 >>= 4;
|
||||
r += 4;
|
||||
}
|
||||
if (u64 >= (U64_LITERAL(1)<<2)) {
|
||||
u64 >>= 2;
|
||||
r += 2;
|
||||
}
|
||||
if (u64 >= (U64_LITERAL(1)<<1)) {
|
||||
// u64 >>= 1; // not using this any more.
|
||||
r += 1;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
/** Return the power of 2 in range [1,UINT64_MAX] closest to <b>u64</b>. If
|
||||
* there are two powers of 2 equally close, round down. */
|
||||
uint64_t
|
||||
round_to_power_of_2(uint64_t u64)
|
||||
{
|
||||
int lg2;
|
||||
uint64_t low;
|
||||
uint64_t high;
|
||||
if (u64 == 0)
|
||||
return 1;
|
||||
|
||||
lg2 = tor_log2(u64);
|
||||
low = U64_LITERAL(1) << lg2;
|
||||
|
||||
if (lg2 == 63)
|
||||
return low;
|
||||
|
||||
high = U64_LITERAL(1) << (lg2+1);
|
||||
if (high - u64 < u64 - low)
|
||||
return high;
|
||||
else
|
||||
return low;
|
||||
}
|
||||
|
||||
/** Return the lowest x such that x is at least <b>number</b>, and x modulo
|
||||
* <b>divisor</b> == 0. If no such x can be expressed as an unsigned, return
|
||||
* UINT_MAX. Asserts if divisor is zero. */
|
||||
unsigned
|
||||
round_to_next_multiple_of(unsigned number, unsigned divisor)
|
||||
{
|
||||
tor_assert(divisor > 0);
|
||||
if (UINT_MAX - divisor + 1 < number)
|
||||
return UINT_MAX;
|
||||
number += divisor - 1;
|
||||
number -= number % divisor;
|
||||
return number;
|
||||
}
|
||||
|
||||
/** Return the lowest x such that x is at least <b>number</b>, and x modulo
|
||||
* <b>divisor</b> == 0. If no such x can be expressed as a uint32_t, return
|
||||
* UINT32_MAX. Asserts if divisor is zero. */
|
||||
uint32_t
|
||||
round_uint32_to_next_multiple_of(uint32_t number, uint32_t divisor)
|
||||
{
|
||||
tor_assert(divisor > 0);
|
||||
if (UINT32_MAX - divisor + 1 < number)
|
||||
return UINT32_MAX;
|
||||
|
||||
number += divisor - 1;
|
||||
number -= number % divisor;
|
||||
return number;
|
||||
}
|
||||
|
||||
/** Return the lowest x such that x is at least <b>number</b>, and x modulo
|
||||
* <b>divisor</b> == 0. If no such x can be expressed as a uint64_t, return
|
||||
* UINT64_MAX. Asserts if divisor is zero. */
|
||||
uint64_t
|
||||
round_uint64_to_next_multiple_of(uint64_t number, uint64_t divisor)
|
||||
{
|
||||
tor_assert(divisor > 0);
|
||||
if (UINT64_MAX - divisor + 1 < number)
|
||||
return UINT64_MAX;
|
||||
number += divisor - 1;
|
||||
number -= number % divisor;
|
||||
return number;
|
||||
}
|
||||
|
||||
/** Transform a random value <b>p</b> from the uniform distribution in
|
||||
* [0.0, 1.0[ into a Laplace distributed value with location parameter
|
||||
* <b>mu</b> and scale parameter <b>b</b>. Truncate the final result
|
||||
@@ -319,68 +220,6 @@ add_laplace_noise(int64_t signal_, double random_, double delta_f,
|
||||
return signal_ + noise;
|
||||
}
|
||||
|
||||
/* Helper: safely add two uint32_t's, capping at UINT32_MAX rather
|
||||
* than overflow */
|
||||
uint32_t
|
||||
tor_add_u32_nowrap(uint32_t a, uint32_t b)
|
||||
{
|
||||
/* a+b > UINT32_MAX check, without overflow */
|
||||
if (PREDICT_UNLIKELY(a > UINT32_MAX - b)) {
|
||||
return UINT32_MAX;
|
||||
} else {
|
||||
return a+b;
|
||||
}
|
||||
}
|
||||
|
||||
/* Helper: return greatest common divisor of a,b */
|
||||
static uint64_t
|
||||
gcd64(uint64_t a, uint64_t b)
|
||||
{
|
||||
while (b) {
|
||||
uint64_t t = b;
|
||||
b = a % b;
|
||||
a = t;
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
/* Given a fraction *<b>numer</b> / *<b>denom</b>, simplify it.
|
||||
* Requires that the denominator is greater than 0. */
|
||||
void
|
||||
simplify_fraction64(uint64_t *numer, uint64_t *denom)
|
||||
{
|
||||
tor_assert(denom);
|
||||
uint64_t gcd = gcd64(*numer, *denom);
|
||||
*numer /= gcd;
|
||||
*denom /= gcd;
|
||||
}
|
||||
|
||||
/** Return the number of bits set in <b>v</b>. */
|
||||
int
|
||||
n_bits_set_u8(uint8_t v)
|
||||
{
|
||||
static const int nybble_table[] = {
|
||||
0, /* 0000 */
|
||||
1, /* 0001 */
|
||||
1, /* 0010 */
|
||||
2, /* 0011 */
|
||||
1, /* 0100 */
|
||||
2, /* 0101 */
|
||||
2, /* 0110 */
|
||||
3, /* 0111 */
|
||||
1, /* 1000 */
|
||||
2, /* 1001 */
|
||||
2, /* 1010 */
|
||||
3, /* 1011 */
|
||||
2, /* 1100 */
|
||||
3, /* 1101 */
|
||||
3, /* 1110 */
|
||||
4, /* 1111 */
|
||||
};
|
||||
|
||||
return nybble_table[v & 15] + nybble_table[v>>4];
|
||||
}
|
||||
|
||||
/* =====
|
||||
* String manipulation
|
||||
* ===== */
|
||||
|
||||
Reference in New Issue
Block a user