MCPcopy Create free account
hub / github.com/apache/impala / ConvertToInt128

Function ConvertToInt128

be/src/runtime/multi-precision.h:93–117  ·  view source on GitHub ↗

Converts an int256_t to an int128_t. int256_t does support convert_to () but that produces an approximate int128_t which makes it unusable. Instead, we'll construct it using convert_to which is exact. overflow is set to true if the value cannot be converted. The return value is undefined in this case.

Source from the content-addressed store, hash-verified

91/// *overflow is set to true if the value cannot be converted. The return value is
92/// undefined in this case.
93inline int128_t ConvertToInt128(int256_t x, int128_t max_value, bool* overflow) {
94 bool negative = false;
95 if (x < 0) {
96 x = -x;
97 negative = true;
98 }
99
100 /// Extract the values in base int64_t::max() and reconstruct the new value
101 /// as an int128_t.
102 uint64_t base = std::numeric_limits<int64_t>::max();
103 int128_t result = 0;
104 int128_t scale = 1;
105 while (x != 0) {
106 uint64_t v = (x % base).convert_to<uint64_t>();
107 x /= base;
108 *overflow |= (v > max_value / scale);
109 int128_t n =
110 ArithmeticUtil::AsUnsigned<std::multiplies>(static_cast<int128_t>(v), scale);
111 *overflow |= (result > ArithmeticUtil::AsUnsigned<std::minus>(max_value, n));
112 result = ArithmeticUtil::AsUnsigned<std::plus>(result, n);
113 scale =
114 ArithmeticUtil::AsUnsigned<std::multiplies>(scale, static_cast<int128_t>(base));
115 }
116 return negative ? ArithmeticUtil::Negate(result) : result;
117}
118
119/// abs() is not defined for int128_t. Name it abs() so it can be compatible with
120/// native int types in templates.

Callers 4

TESTFunction · 0.85
MultiplyMethod · 0.85
DivideMethod · 0.85
ModMethod · 0.85

Calls 1

maxFunction · 0.85

Tested by 1

TESTFunction · 0.68