Skip to content

Commit 4817bb1

Browse files
committed
Use std::frexp for log2 approx
1 parent 3e99a5f commit 4817bb1

3 files changed

Lines changed: 32 additions & 44 deletions

File tree

ddsketch/include/linearly_interpolated_mapping_impl.hpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,17 @@ inline LinearlyInterpolatedMapping::LinearlyInterpolatedMapping(const double& ga
3232
LogLikeIndexMapping<LinearlyInterpolatedMapping>(gamma, index_offset) {}
3333

3434
inline double LinearlyInterpolatedMapping::log(const double& value) const {
35-
return fast_log2(value);
35+
int exponent = 0;
36+
const double mantissa = std::frexp(value, &exponent);
37+
const double significand = 2 * mantissa - 1;
38+
return significand + (exponent - 1);
39+
3640
}
3741

3842
inline double LinearlyInterpolatedMapping::log_inverse(const double& index) const {
39-
return fast_log2_inverse(index);
43+
int exponent = static_cast<int>(std::floor(index)) + 1;
44+
double mantissa = (index - exponent + 2) / 2.0;
45+
return std::ldexp(mantissa, exponent);
4046
}
4147

4248
inline IndexMappingLayout LinearlyInterpolatedMapping::layout() const {

ddsketch/include/quadratically_interpolated_mapping_impl.hpp

Lines changed: 15 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -32,32 +32,26 @@ inline QuadraticallyInterpolatedMapping::QuadraticallyInterpolatedMapping(const
3232

3333

3434
inline double QuadraticallyInterpolatedMapping::log(const double& value) const {
35-
int64_t value_bits;
36-
std::memcpy(&value_bits, &value, sizeof(value));
37-
38-
const int64_t mantissa_plus_one_bits = (value_bits & 0x000FFFFFFFFFFFFFL) | 0x3FF0000000000000L;
39-
double mantissa_plus_one;
40-
std::memcpy(&mantissa_plus_one, &mantissa_plus_one_bits, sizeof(mantissa_plus_one_bits));
41-
42-
const double exponent = static_cast<double>(((value_bits & 0x7FF0000000000000L) >> 52) - 1023);
43-
44-
return exponent - (mantissa_plus_one - 5.0) * (mantissa_plus_one - 1) * ONE_THIRD;
35+
// int64_t value_bits;
36+
// std::memcpy(&value_bits, &value, sizeof(value));
37+
//
38+
// const int64_t mantissa_plus_one_bits = (value_bits & 0x000FFFFFFFFFFFFFL) | 0x3FF0000000000000L;
39+
// double mantissa_plus_one;
40+
// std::memcpy(&mantissa_plus_one, &mantissa_plus_one_bits, sizeof(mantissa_plus_one_bits));
41+
//
42+
// const double exponent = static_cast<double>(((value_bits & 0x7FF0000000000000L) >> 52) - 1023);
43+
44+
int exponent = 0;
45+
const double mantissa = 2 * std::frexp(value, &exponent);
46+
47+
return exponent - 1 - (mantissa - 5.0) * (mantissa- 1) * ONE_THIRD;
4548
}
4649

4750
inline double QuadraticallyInterpolatedMapping::log_inverse(const double& index) const {
48-
const int64_t exponent = static_cast<int64_t>(std::floor(index));
51+
const int exponent = static_cast<int>(std::floor(index));
4952
const double mantissa_plus_one = 3.0 - std::sqrt(4.0 - 3.0 * (index - exponent));
5053

51-
int64_t result_bits = (static_cast<uint64_t>(exponent + 1023) << 52) & 0x7FF0000000000000L;
52-
53-
uint64_t mantissa_plus_one_bits;
54-
std::memcpy(&mantissa_plus_one_bits, &mantissa_plus_one, sizeof(mantissa_plus_one));
55-
56-
result_bits |= (mantissa_plus_one_bits & 0x000FFFFFFFFFFFFFL);
57-
58-
double result;
59-
std::memcpy(&result, &result_bits, sizeof(result_bits));
60-
return result;
54+
return std::ldexp(mantissa_plus_one, exponent);
6155
}
6256

6357
inline IndexMappingLayout QuadraticallyInterpolatedMapping::layout() const {

ddsketch/include/quartically_interpolated_mapping_impl.hpp

Lines changed: 9 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -29,21 +29,15 @@ inline QuarticallyInterpolatedMapping::QuarticallyInterpolatedMapping(const doub
2929
LogLikeIndexMapping<QuarticallyInterpolatedMapping>(gamma, index_offset) {}
3030

3131
inline double QuarticallyInterpolatedMapping::log(const double &value) const {
32-
int64_t value_bits;
33-
std::memcpy(&value_bits, &value, sizeof(value_bits));
32+
int exponent = 0;
33+
const double mantissa = 2 * std::frexp(value, &exponent) - 1;
3434

35-
const int64_t mantissa_plus_one_bits = (value_bits & 0x000FFFFFFFFFFFFFL) | 0x3FF0000000000000L;
36-
double mantissa_plus_one;
37-
std::memcpy(&mantissa_plus_one, &mantissa_plus_one_bits, sizeof(mantissa_plus_one_bits));
38-
double mantissa = mantissa_plus_one - 1.0;
39-
40-
const double exponent = static_cast<double>(((value_bits & 0x7FF0000000000000L) >> 52) - 1023);
41-
return (((A * mantissa + B) * mantissa + C) * mantissa + D) * mantissa + exponent;
35+
return (((A * mantissa + B) * mantissa + C) * mantissa + D) * mantissa + exponent - 1;
4236
}
4337

4438
inline double QuarticallyInterpolatedMapping::log_inverse(const double &index) const {
45-
const int64_t exponent = static_cast<int64_t>(std::floor(index));
46-
const double e = exponent - index;
39+
const auto exponent = static_cast<int>(std::floor(index));
40+
const double e = static_cast<double>(exponent) - index;
4741

4842
// Derived from Ferrari's method
4943
const double alpha = -(3 * B * B) / (8 * A * A) + C / A; // 2.5
@@ -57,16 +51,10 @@ inline double QuarticallyInterpolatedMapping::log_inverse(const double &index) c
5751
const double w = std::sqrt(alpha + 2 * y);
5852
const double x = (-B / (4 * A) + (w - std::sqrt(-(3 * alpha + 2 * y + (2 * beta) / w))) / 2) + 1;
5953

60-
int64_t result_bits = (static_cast<uint64_t>(exponent + 1023) << 52) & 0x7FF0000000000000L;
61-
62-
uint64_t x_plus_one_bits;
63-
std::memcpy(&x_plus_one_bits, &x, sizeof(x));
64-
65-
result_bits |= (x_plus_one_bits & 0x000FFFFFFFFFFFFFL);
66-
67-
double result;
68-
std::memcpy(&result, &result_bits, sizeof(result_bits));
69-
return result;
54+
int tmp = 0;
55+
double m = std::frexp(x, &tmp);
56+
double sig = 2.0 * m;
57+
return std::ldexp(sig, exponent);
7058
}
7159

7260
inline IndexMappingLayout QuarticallyInterpolatedMapping::layout() const {

0 commit comments

Comments
 (0)