10 #ifndef EIGEN_CXX11_TENSOR_TENSOR_UINT128_H
11 #define EIGEN_CXX11_TENSOR_TENSOR_UINT128_H
19 static const uint64_t value = n;
20 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
operator uint64_t()
const {
return n; }
22 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE static_val() { }
24 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE static_val(
const T& v) {
30 template <
typename HIGH = u
int64_t,
typename LOW = u
int64_t>
36 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
37 TensorUInt128(
int x) : high(0), low(x) {
40 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
41 TensorUInt128(int64_t x) : high(0), low(x) {
44 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
45 TensorUInt128(uint64_t x) : high(0), low(x) { }
46 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
47 TensorUInt128(uint64_t y, uint64_t x) : high(y), low(x) { }
49 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
operator LOW()
const {
52 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE LOW lower()
const {
55 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE HIGH upper()
const {
61 template <
typename HL,
typename LL,
typename HR,
typename LR>
62 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
63 static bool operator == (
const TensorUInt128<HL, LL>& lhs,
const TensorUInt128<HR, LR>& rhs)
65 return (lhs.high == rhs.high) & (lhs.low == rhs.low);
68 template <
typename HL,
typename LL,
typename HR,
typename LR>
69 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
70 static bool operator != (
const TensorUInt128<HL, LL>& lhs,
const TensorUInt128<HR, LR>& rhs)
72 return (lhs.high != rhs.high) | (lhs.low != rhs.low);
75 template <
typename HL,
typename LL,
typename HR,
typename LR>
76 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
77 static bool operator >= (
const TensorUInt128<HL, LL>& lhs,
const TensorUInt128<HR, LR>& rhs)
79 if (lhs.high != rhs.high) {
80 return lhs.high > rhs.high;
82 return lhs.low >= rhs.low;
85 template <
typename HL,
typename LL,
typename HR,
typename LR>
86 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
87 static bool operator < (const TensorUInt128<HL, LL>& lhs,
const TensorUInt128<HR, LR>& rhs)
89 if (lhs.high != rhs.high) {
90 return lhs.high < rhs.high;
92 return lhs.low < rhs.low;
95 template <
typename HL,
typename LL,
typename HR,
typename LR>
96 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
97 static TensorUInt128<uint64_t, uint64_t> operator + (
const TensorUInt128<HL, LL>& lhs,
const TensorUInt128<HR, LR>& rhs)
99 TensorUInt128<uint64_t, uint64_t> result(lhs.high + rhs.high, lhs.low + rhs.low);
100 if (result.low < rhs.low) {
106 template <
typename HL,
typename LL,
typename HR,
typename LR>
107 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
108 static TensorUInt128<uint64_t, uint64_t> operator - (
const TensorUInt128<HL, LL>& lhs,
const TensorUInt128<HR, LR>& rhs)
110 TensorUInt128<uint64_t, uint64_t> result(lhs.high - rhs.high, lhs.low - rhs.low);
111 if (result.low > lhs.low) {
118 template <
typename HL,
typename LL,
typename HR,
typename LR>
119 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
120 static TensorUInt128<uint64_t, uint64_t> operator * (
const TensorUInt128<HL, LL>& lhs,
const TensorUInt128<HR, LR>& rhs)
133 const uint64_t LOW = 0x00000000FFFFFFFFLL;
134 const uint64_t HIGH = 0xFFFFFFFF00000000LL;
136 uint64_t d = lhs.low & LOW;
137 uint64_t c = (lhs.low & HIGH) >> 32LL;
138 uint64_t b = lhs.high & LOW;
139 uint64_t a = (lhs.high & HIGH) >> 32LL;
141 uint64_t h = rhs.low & LOW;
142 uint64_t g = (rhs.low & HIGH) >> 32LL;
143 uint64_t f = rhs.high & LOW;
144 uint64_t e = (rhs.high & HIGH) >> 32LL;
147 uint64_t acc = d * h;
148 uint64_t low = acc & LOW;
152 uint64_t acc2 = acc + c * h;
160 low |= (acc << 32LL);
164 acc2 = (acc >> 32LL) | (carry << 32LL);
179 uint64_t high = acc & LOW;
182 acc2 = (acc >> 32LL) | (carry << 32LL);
188 high |= (acc2 << 32LL);
190 return TensorUInt128<uint64_t, uint64_t>(high, low);
193 template <
typename HL,
typename LL,
typename HR,
typename LR>
194 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
195 static TensorUInt128<uint64_t, uint64_t> operator / (
const TensorUInt128<HL, LL>& lhs,
const TensorUInt128<HR, LR>& rhs)
197 if (rhs == TensorUInt128<static_val<0>, static_val<1> >(1)) {
198 return TensorUInt128<uint64_t, uint64_t>(lhs.high, lhs.low);
199 }
else if (lhs < rhs) {
200 return TensorUInt128<uint64_t, uint64_t>(0);
203 TensorUInt128<uint64_t, uint64_t> power2(1);
204 TensorUInt128<uint64_t, uint64_t> d(rhs);
205 TensorUInt128<uint64_t, uint64_t> tmp(lhs - d);
209 power2 = power2 + power2;
212 tmp = TensorUInt128<uint64_t, uint64_t>(lhs.high, lhs.low);
213 TensorUInt128<uint64_t, uint64_t> result(0);
214 while (power2 != TensorUInt128<static_val<0>, static_val<0> >(0)) {
217 result = result + power2;
220 power2 = TensorUInt128<uint64_t, uint64_t>(power2.high >> 1, (power2.low >> 1) | (power2.high << 63));
221 d = TensorUInt128<uint64_t, uint64_t>(d.high >> 1, (d.low >> 1) | (d.high << 63));
233 #endif // EIGEN_CXX11_TENSOR_TENSOR_UINT128_H
Namespace containing all symbols from the Eigen library.
Definition: CXX11Meta.h:13