Impala
Impalaistheopensource,nativeanalyticdatabaseforApacheHadoop.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
multi-precision.h
Go to the documentation of this file.
1 // Copyright 2012 Cloudera Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef IMPALA_RUNTIME_MULTI_PRECISION_H
16 #define IMPALA_RUNTIME_MULTI_PRECISION_H
17 
18 
21 #include <boost/version.hpp>
22 #if BOOST_VERSION < 105000
23 #define BOOST_NOEXCEPT
26 #define BOOST_NOEXCEPT_IF(Predicate)
27 #define BOOST_FORCEINLINE inline __attribute__ ((__always_inline__))
28 
29 #define BOOST_NO_CXX11_CONSTEXPR
30 #define BOOST_NO_CXX11_DECLTYPE
31 #define BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS
32 #define BOOST_NO_CXX11_HDR_ARRAY
33 #define BOOST_NO_CXX11_RVALUE_REFERENCES
34 #define BOOST_NO_CXX11_USER_DEFINED_LITERALS
35 #define BOOST_NO_CXX11_VARIADIC_TEMPLATES
36 
38 #include "boost_multiprecision/cpp_int.hpp"
39 #include "boost_multiprecision/cpp_dec_float.hpp"
40 
41 #else
42 #include <boost/multiprecision/cpp_int.hpp>
43 #include <boost/multiprecision/cpp_dec_float.hpp>
44 #endif
45 
46 #include <limits>
47 
48 namespace impala {
49 
51 typedef __int128_t int128_t;
52 
54 typedef boost::multiprecision::number<
55  boost::multiprecision::cpp_int_backend<256, 256,
56  boost::multiprecision::signed_magnitude,
57  boost::multiprecision::unchecked, void> > int256_t;
58 
64 inline int256_t ConvertToInt256(const int128_t& x) {
65  if (x < 0) {
66  uint64_t hi = static_cast<uint64_t>(-x >> 64);
67  uint64_t lo = static_cast<uint64_t>(-x);
68  int256_t v = hi;
69  v <<= 64;
70  v |= lo;
71  return -v;
72  } else {
73  uint64_t hi = static_cast<uint64_t>(x >> 64);
74  uint64_t lo = static_cast<uint64_t>(x);
75  int256_t v = hi;
76  v <<= 64;
77  v |= lo;
78  return v;
79  }
80 }
81 
87 inline int128_t ConvertToInt128(int256_t x, int128_t max_value, bool* overflow) {
88  bool negative = false;
89  if (x < 0) {
90  x = -x;
91  negative = true;
92  }
93 
96  uint64_t base = std::numeric_limits<int64_t>::max();
97  int128_t result = 0;
98  int128_t scale = 1;
99  while (x != 0) {
100  uint64_t v = (x % base).convert_to<uint64_t>();
101  x /= base;
102  *overflow |= (v > max_value / scale);
103  int128_t n = v * scale;
104  *overflow |= (result > max_value - n);
105  result += n;
106  scale *= base;
107  }
108  return negative ? -result : result;
109 }
110 
113 inline int128_t abs(const int128_t& x) { return (x < 0) ? -x : x; }
114 
117  return x >> 64;
118 }
120  return x & 0xffffffffffffffff;
121 }
122 
124 std::ostream& operator<<(std::ostream& os, const int128_t& val);
125 
126 }
127 
128 #endif
int128_t abs(const int128_t &x)
int128_t ConvertToInt128(int256_t x, int128_t max_value, bool *overflow)
boost::multiprecision::number< boost::multiprecision::cpp_int_backend< 256, 256, boost::multiprecision::signed_magnitude, boost::multiprecision::unchecked, void > > int256_t
Define 256 bit int type.
int256_t ConvertToInt256(const int128_t &x)
uint64_t LowBits(int128_t x)
uint64_t HighBits(int128_t x)
Get the high and low bits of an int128_t.
ostream & operator<<(ostream &os, const map< TNetworkAddress, llama::TAllocatedResource > &resources)
__int128_t int128_t
We use the c++ int128_t type. This is stored using 16 bytes and very performant.