14 #ifndef OR_TOOLS_UTIL_SATURATED_ARITHMETIC_H_ 15 #define OR_TOOLS_UTIL_SATURATED_ARITHMETIC_H_ 17 #include "absl/base/casts.h" 39 static_assert(static_cast<uint64_t>(-1LL) == ~0ULL,
40 "The target architecture does not use two's complement.");
41 return absl::bit_cast<int64_t>(static_cast<uint64_t>(x) +
42 static_cast<uint64_t>(y));
46 static_assert(static_cast<uint64_t>(-1LL) == ~0ULL,
47 "The target architecture does not use two's complement.");
48 return absl::bit_cast<int64_t>(static_cast<uint64_t>(x) -
49 static_cast<uint64_t>(y));
60 return ((x ^ sum) & (y ^ sum)) < 0;
88 template <
typename IntegerType>
90 const int64_t x =
a.value();
91 const int64_t y =
b->value();
109 #if defined(__GNUC__) && defined(__x86_64__) 111 inline int64_t CapAddFast(int64_t x, int64_t y) {
116 "\t" "addq %[y],%[result]" 117 "\n\t" "cmovoq %[cap],%[result]" 118 : [result]
"=r"(result)
119 :
"[result]" (result), [y]
"r"(y), [cap]
"r"(cap)
126 inline int64_t
CapAdd(int64_t x, int64_t y) {
127 #if defined(__GNUC__) && defined(__x86_64__) 128 return CapAddFast(x, y);
141 #if defined(__GNUC__) && defined(__x86_64__) 143 inline int64_t CapSubFast(int64_t x, int64_t y) {
148 "\t" "subq %[y],%[result]" 149 "\n\t" "cmovoq %[cap],%[result]" 150 : [result]
"=r"(result)
151 :
"[result]" (result), [y]
"r"(y), [cap]
"r"(cap)
158 inline int64_t
CapSub(int64_t x, int64_t y) {
159 #if defined(__GNUC__) && defined(__x86_64__) 160 return CapSubFast(x, y);
169 namespace cap_prod_util {
173 return n < 0 ? ~static_cast<uint64_t>(n) + 1 : static_cast<uint64_t>(n);
191 const int kMaxBitIndexInInt64 = 63;
192 if (msb_sum <= kMaxBitIndexInInt64 - 2)
return x * y;
195 if (
a == 0 ||
b == 0)
return 0;
197 if (msb_sum >= kMaxBitIndexInInt64)
return cap;
201 const uint64_t u_prod =
a *
b;
207 if (u_prod >= static_cast<uint64_t>(cap))
return cap;
208 const int64_t abs_result = absl::bit_cast<int64_t>(u_prod);
209 return cap < 0 ? -abs_result : abs_result;
212 #if defined(__GNUC__) && defined(__x86_64__) 214 inline int64_t CapProdFast(int64_t x, int64_t y) {
225 "\n\t" "imulq %[y],%[result]" 226 "\n\t" "cmovcq %[cap],%[result]" 227 : [result]
"=r"(result)
228 :
"[result]" (result), [y]
"r"(y), [cap]
"r"(cap)
235 inline int64_t
CapProd(int64_t x, int64_t y) {
236 #if defined(__GNUC__) && defined(__x86_64__) 237 return CapProdFast(x, y);
244 #endif // OR_TOOLS_UTIL_SATURATED_ARITHMETIC_H_ bool AddHadOverflow(int64_t x, int64_t y, int64_t sum)
bool SafeAddInto(IntegerType a, IntegerType *b)
int64_t CapSub(int64_t x, int64_t y)
int64_t CapSubGeneric(int64_t x, int64_t y)
int64_t CapOpp(int64_t v)
int64_t CapProd(int64_t x, int64_t y)
void CapAddTo(int64_t x, int64_t *y)
static const int64_t kint64min
int MostSignificantBitPosition64(uint64_t n)
static const int64_t kint64max
int64_t CapAdd(int64_t x, int64_t y)
uint64_t uint_abs(int64_t n)
int64_t CapWithSignOf(int64_t x)
bool AddOverflows(int64_t x, int64_t y)
bool SubHadOverflow(int64_t x, int64_t y, int64_t diff)
#define DCHECK_EQ(val1, val2)
int64_t TwosComplementSubtraction(int64_t x, int64_t y)
Collection of objects used to extend the Constraint Solver library.
int64_t SubOverflows(int64_t x, int64_t y)
int64_t CapProdGeneric(int64_t x, int64_t y)
int64_t TwosComplementAddition(int64_t x, int64_t y)
int64_t CapAddGeneric(int64_t x, int64_t y)