16 #ifndef IMPALA_UTIL_DECIMAL_UTIL_H
17 #define IMPALA_UTIL_DECIMAL_UTIL_H
21 #include <boost/cstdint.hpp>
46 return v * GetScaleMultiplier<T>(scale);
53 for (
int i = 0; i < scale; ++i) {
62 uint8_t* buffer,
int fixed_len_size,
const T& v) {
63 DCHECK_GT(fixed_len_size, 0);
64 DCHECK_LE(fixed_len_size,
sizeof(T));
66 #if __BYTE_ORDER == __LITTLE_ENDIAN
69 memcpy(buffer, &v +
sizeof(T) - fixed_len_size, fixed_len_size);
73 #if __BYTE_ORDER == __LITTLE_ENDIAN
74 const int8_t* skipped_bytes_start =
reinterpret_cast<const int8_t*
>(&v) +
77 const int8_t* skipped_bytes_start =
reinterpret_cast<const int8_t*
>(&v);
80 for (
int i = 0; i <
sizeof(T) - fixed_len_size; ++i) {
81 DCHECK_EQ(skipped_bytes_start[i], v.value() < 0 ? -1 : 0);
88 const uint8_t* buffer,
int fixed_len_size, T* v) {
89 DCHECK_GT(fixed_len_size, 0);
90 DCHECK_LE(fixed_len_size,
sizeof(T));
98 int bytes_to_fill =
sizeof(T) - fixed_len_size;
99 #if __BYTE_ORDER == __LITTLE_ENDIAN
100 BitUtil::ByteSwap(reinterpret_cast<int8_t*>(v) + bytes_to_fill, buffer, fixed_len_size);
102 memcpy(v, buffer, fixed_len_size);
104 v->value() >>= (bytes_to_fill * 8);
109 inline int32_t DecimalUtil::GetScaleMultiplier<int32_t>(
int scale) {
111 static const int32_t values[] = {
123 if (
LIKELY(scale < 10))
return values[scale];
128 inline int64_t DecimalUtil::GetScaleMultiplier<int64_t>(
int scale) {
130 static const int64_t values[] = {
148 100000000000000000ll,
149 1000000000000000000ll};
151 if (
LIKELY(scale < 19))
return values[scale];
156 inline int128_t DecimalUtil::GetScaleMultiplier<int128_t>(
int scale) {
160 static_cast<int128_t>(10ll),
162 static_cast<int128_t>(1000ll),
164 static_cast<int128_t>(100000ll),
166 static_cast<int128_t>(10000000ll),
168 static_cast<int128_t>(1000000000ll),
169 static_cast<int128_t>(10000000000ll),
170 static_cast<int128_t>(100000000000ll),
171 static_cast<int128_t>(1000000000000ll),
172 static_cast<int128_t>(10000000000000ll),
173 static_cast<int128_t>(100000000000000ll),
174 static_cast<int128_t>(1000000000000000ll),
175 static_cast<int128_t>(10000000000000000ll),
176 static_cast<int128_t>(100000000000000000ll),
177 static_cast<int128_t>(1000000000000000000ll),
178 static_cast<int128_t>(1000000000000000000ll) * 10ll,
179 static_cast<int128_t>(1000000000000000000ll) * 100ll,
180 static_cast<int128_t>(1000000000000000000ll) * 1000ll,
181 static_cast<int128_t>(1000000000000000000ll) * 10000ll,
182 static_cast<int128_t>(1000000000000000000ll) * 100000ll,
183 static_cast<int128_t>(1000000000000000000ll) * 1000000ll,
184 static_cast<int128_t>(1000000000000000000ll) * 10000000ll,
185 static_cast<int128_t>(1000000000000000000ll) * 100000000ll,
186 static_cast<int128_t>(1000000000000000000ll) * 1000000000ll,
187 static_cast<int128_t>(1000000000000000000ll) * 10000000000ll,
188 static_cast<int128_t>(1000000000000000000ll) * 100000000000ll,
189 static_cast<int128_t>(1000000000000000000ll) * 1000000000000ll,
190 static_cast<int128_t>(1000000000000000000ll) * 10000000000000ll,
191 static_cast<int128_t>(1000000000000000000ll) * 100000000000000ll,
192 static_cast<int128_t>(1000000000000000000ll) * 1000000000000000ll,
193 static_cast<int128_t>(1000000000000000000ll) * 10000000000000000ll,
194 static_cast<int128_t>(1000000000000000000ll) * 100000000000000000ll,
195 static_cast<int128_t>(1000000000000000000ll) * 100000000000000000ll * 10ll,
196 static_cast<int128_t>(1000000000000000000ll) * 100000000000000000ll * 100ll,
197 static_cast<int128_t>(1000000000000000000ll) * 100000000000000000ll * 1000ll};
199 if (
LIKELY(scale < 39))
return values[scale];
static void DecodeFromFixedLenByteArray(const uint8_t *buffer, int fixed_len_size, T *v)
static T MultiplyByScale(const T &v, int scale)
static const int MAX_DECIMAL8_PRECISION
The maximum precision representable by a 8-byte decimal (Decimal8Value)
static void EncodeToFixedLenByteArray(uint8_t *buffer, int fixed_len_size, const T &v)
Write decimals as big endian (byte comparable) in fixed_len_size bytes.
static int64_t ByteSwap(int64_t value)
Swaps the byte order (i.e. endianess)
static int128_t MAX_UNSCALED_DECIMAL
Maximum absolute value of int128_t that we use. This is 38 digits of 9's.
static T MultiplyByScale(const T &v, const ColumnType &t)
TODO: do we need to handle overflow here or at a higher abstraction.
static T GetScaleMultiplier(int scale)
static void InitMaxUnscaledDecimal()
Initializes MAX_UNSCALED_DECIMAL. Must be called once before using it.
static const int MAX_DECIMAL4_PRECISION
The maximum precision representable by a 4-byte decimal (Decimal4Value)
static const int MAX_PRECISION
Must be kept in sync with FE's max precision/scale.
__int128_t int128_t
We use the c++ int128_t type. This is stored using 16 bytes and very performant.