Skip to content

Commit c272c55

Browse files
committed
fix: use int128_t as Decimal data
1 parent 026dfc9 commit c272c55

File tree

2 files changed

+14
-27
lines changed

2 files changed

+14
-27
lines changed

src/iceberg/util/decimal.cc

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -419,14 +419,12 @@ Decimal& Decimal::operator/=(const Decimal& other) {
419419
}
420420

421421
Decimal& Decimal::operator|=(const Decimal& other) {
422-
data_[0] |= other.data_[0];
423-
data_[1] |= other.data_[1];
422+
data_ |= other.data_;
424423
return *this;
425424
}
426425

427426
Decimal& Decimal::operator&=(const Decimal& other) {
428-
data_[0] &= other.data_[0];
429-
data_[1] &= other.data_[1];
427+
data_ &= other.data_;
430428
return *this;
431429
}
432430

@@ -1376,7 +1374,7 @@ double Decimal::ToDouble(int32_t scale) const {
13761374

13771375
std::array<uint8_t, Decimal::kByteWidth> Decimal::ToBytes() const {
13781376
std::array<uint8_t, kByteWidth> out{{0}};
1379-
memcpy(out.data(), data_.data(), kByteWidth);
1377+
memcpy(out.data(), &data_, kByteWidth);
13801378
return out;
13811379
}
13821380

src/iceberg/util/decimal.h

Lines changed: 11 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636

3737
#include "iceberg/iceberg_export.h"
3838
#include "iceberg/result.h"
39+
#include "iceberg/util/int128.h"
3940
#include "iceberg/util/macros.h"
4041

4142
namespace iceberg {
@@ -51,34 +52,22 @@ class ICEBERG_EXPORT Decimal {
5152
static constexpr int32_t kMaxScale = 38;
5253

5354
/// \brief Default constructor initializes to zero.
54-
constexpr Decimal() noexcept : data_{0, 0} {}
55-
56-
/// \brief Construct a Decimal from an array of 2 64-bit integers.
57-
explicit Decimal(std::array<uint64_t, 2> data) noexcept : data_(std::move(data)) {}
55+
constexpr Decimal() noexcept = default;
5856

5957
/// \brief Create a Decimal from any integer not wider than 64 bits.
6058
template <typename T>
6159
requires(std::is_integral_v<T> && (sizeof(T) <= sizeof(uint64_t)))
6260
constexpr Decimal(T value) noexcept // NOLINT
6361
{
64-
if (value < T{}) {
65-
data_[highIndex()] = ~static_cast<uint64_t>(0);
66-
} else {
67-
data_[highIndex()] = 0;
68-
}
69-
data_[lowIndex()] = static_cast<uint64_t>(value);
62+
data_ = static_cast<int128_t>(value);
7063
}
7164

7265
/// \brief Parse a Decimal from a string representation.
7366
explicit Decimal(std::string_view str);
7467

7568
/// \brief Create a Decimal from two 64-bit integers.
7669
constexpr Decimal(int64_t high, uint64_t low) noexcept {
77-
if constexpr (std::endian::native == std::endian::little) {
78-
data_ = {low, static_cast<uint64_t>(high)};
79-
} else {
80-
data_ = {static_cast<uint64_t>(high), low};
81-
}
70+
data_ = (static_cast<int128_t>(high) << 64) | low;
8271
}
8372

8473
/// \brief Negate the current Decimal value (in place)
@@ -141,10 +130,10 @@ class ICEBERG_EXPORT Decimal {
141130
}
142131

143132
/// \brief Get the high bits of the two's complement representation of the number.
144-
constexpr int64_t high() const { return static_cast<int64_t>(data_[highIndex()]); }
133+
constexpr int64_t high() const { return static_cast<int64_t>(data_ >> 64); }
145134

146135
/// \brief Get the low bits of the two's complement representation of the number.
147-
constexpr uint64_t low() const { return data_[lowIndex()]; }
136+
constexpr uint64_t low() const { return static_cast<uint64_t>(data_); }
148137

149138
/// \brief Convert the Decimal value to a base 10 decimal string with the given scale.
150139
/// \param scale The scale to use for the string representation.
@@ -229,19 +218,19 @@ class ICEBERG_EXPORT Decimal {
229218
}
230219

231220
const uint8_t* native_endian_bytes() const {
232-
return reinterpret_cast<const uint8_t*>(data_.data());
221+
return reinterpret_cast<const uint8_t*>(data_);
233222
}
234223

235224
/// \brief Returns the raw bytes of the value in native-endian byte order.
236225
std::array<uint8_t, kByteWidth> ToBytes() const;
237226

238227
/// \brief Returns 1 if positive or zero, -1 if strictly negative.
239-
int64_t Sign() const { return 1 | (static_cast<int64_t>(data_[highIndex()]) >> 63); }
228+
int64_t Sign() const { return 1 | (high() >> 63); }
240229

241230
/// \brief Check if the Decimal value is negative.
242-
bool IsNegative() const { return static_cast<int64_t>(data_[highIndex()]) < 0; }
231+
bool IsNegative() const { return (high() >> 63) < 0; }
243232

244-
explicit operator bool() const { return data_ != std::array<uint64_t, 2>{0, 0}; }
233+
explicit operator bool() const { return data_ != 0; }
245234

246235
friend bool operator==(const Decimal& lhs, const Decimal& rhs) {
247236
return lhs.data_ == rhs.data_;
@@ -268,7 +257,7 @@ class ICEBERG_EXPORT Decimal {
268257
}
269258
}
270259

271-
std::array<uint64_t, 2> data_;
260+
int128_t data_{0};
272261
};
273262

274263
ICEBERG_EXPORT std::ostream& operator<<(std::ostream& os, const Decimal& decimal);

0 commit comments

Comments
 (0)