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;
88template <
typename IntegerType>
90 const int64_t x =
a.value();
91 const int64_t y =
b->value();
109#if defined(__GNUC__) && defined(__x86_64__)
111inline 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)
126inline 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__)
141inline 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)
156inline int64_t
CapSub(int64_t x, int64_t y) {
157#if defined(__GNUC__) && defined(__x86_64__)
158 return CapSubFast(x, y);
167namespace 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__)
212inline 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)
234#if defined(__GNUC__) && defined(__x86_64__)
235 return CapProdFast(x, y);
#define DCHECK_EQ(val1, val2)
static const int64_t kint64max
static const int64_t kint64min
uint64_t uint_abs(int64_t n)
Collection of objects used to extend the Constraint Solver library.
int64_t SubOverflows(int64_t x, int64_t y)
bool AddHadOverflow(int64_t x, int64_t y, int64_t sum)
int64_t CapAdd(int64_t x, int64_t y)
int64_t CapWithSignOf(int64_t x)
int64_t TwosComplementAddition(int64_t x, int64_t y)
int64_t CapSub(int64_t x, int64_t y)
int64_t CapAddGeneric(int64_t x, int64_t y)
bool AddOverflows(int64_t x, int64_t y)
int64_t CapProd(int64_t x, int64_t y)
bool SubHadOverflow(int64_t x, int64_t y, int64_t diff)
int64_t TwosComplementSubtraction(int64_t x, int64_t y)
int64_t CapProdGeneric(int64_t x, int64_t y)
bool SafeAddInto(IntegerType a, IntegerType *b)
int64_t CapSubGeneric(int64_t x, int64_t y)
int64_t CapOpp(int64_t v)
int MostSignificantBitPosition64(uint64_t n)