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);
139 #if defined(__GNUC__) && defined(__x86_64__) 141 inline int64_t CapSubFast(int64_t x, int64_t y) {
146 "\t" "subq %[y],%[result]" 147 "\n\t" "cmovoq %[cap],%[result]" 148 : [result]
"=r"(result)
149 :
"[result]" (result), [y]
"r"(y), [cap]
"r"(cap)
156 inline int64_t
CapSub(int64_t x, int64_t y) {
157 #if defined(__GNUC__) && defined(__x86_64__) 158 return CapSubFast(x, y);
167 namespace cap_prod_util {
171 return n < 0 ? ~static_cast<uint64_t>(n) + 1 : static_cast<uint64_t>(n);
189 const int kMaxBitIndexInInt64 = 63;
190 if (msb_sum <= kMaxBitIndexInInt64 - 2)
return x * y;
193 if (
a == 0 ||
b == 0)
return 0;
195 if (msb_sum >= kMaxBitIndexInInt64)
return cap;
199 const uint64_t u_prod =
a *
b;
205 if (u_prod >= static_cast<uint64_t>(cap))
return cap;
206 const int64_t abs_result = absl::bit_cast<int64_t>(u_prod);
207 return cap < 0 ? -abs_result : abs_result;
210 #if defined(__GNUC__) && defined(__x86_64__) 212 inline int64_t CapProdFast(int64_t x, int64_t y) {
223 "\n\t" "imulq %[y],%[result]" 224 "\n\t" "cmovcq %[cap],%[result]" 225 : [result]
"=r"(result)
226 :
"[result]" (result), [y]
"r"(y), [cap]
"r"(cap)
233 inline int64_t
CapProd(int64_t x, int64_t y) {
234 #if defined(__GNUC__) && defined(__x86_64__) 235 return CapProdFast(x, y);
242 #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)
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)