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);
141#if defined(__GNUC__) && defined(__x86_64__)
143inline 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)
158inline int64_t
CapSub(int64_t x, int64_t y) {
159#if defined(__GNUC__) && defined(__x86_64__)
160 return CapSubFast(x, y);
169namespace 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__)
214inline 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)
236#if defined(__GNUC__) && defined(__x86_64__)
237 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)
void CapAddTo(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)