Google OR-Tools: ortools/util/saturated_arithmetic.h Source File
14#ifndef ORTOOLS_UTIL_SATURATED_ARITHMETIC_H_
15#define ORTOOLS_UTIL_SATURATED_ARITHMETIC_H_
21#include "absl/base/casts.h"
59inline int64_t CapOpp(int64_t v) { return v == kint64min ? ~v : -v; }
83 static_assert(static_cast<uint64_t>(-1LL) == ~0ULL,
84 "The target architecture does not use two's complement.");
85 return absl::bit_cast<int64_t>(static_cast<uint64_t>(x) +
90 static_assert(static_cast<uint64_t>(-1LL) == ~0ULL,
91 "The target architecture does not use two's complement.");
92 return absl::bit_cast<int64_t>(static_cast<uint64_t>(x) -
98inline bool AddHadOverflow(int64_t x, int64_t y, int64_t sum) {
132template <typename IntegerType>
152#if defined(__GNUC__) && !defined(__clang_) && defined(__x86_64__)
153inline int64_t CapAddAsm(int64_t x, int64_t y) {
158 "\t" "addq %[y],%[result]"
159 "\n\t" "cmovoq %[cap],%[result]"
161 : "[result]" (result), [y] "r"(y), [cap] "r"(cap)
167inline int64_t CapSubAsm(int64_t x, int64_t y) {
169 int64_t result = x;
172 "\t" "subq %[y],%[result]"
173 "\n\t" "cmovoq %[cap],%[result]"
175 : "[result]" (result), [y] "r"(y), [cap] "r"(cap)
183inline int64_t CapProdAsm(int64_t x, int64_t y) {
187 int64_t result = x;
194 "\n\t" "imulq %[y],%[result]"
195 "\n\t" "cmovcq %[cap],%[result]"
197 : "[result]" (result), [y] "r"(y), [cap] "r"(cap)
208inline int64_t CapAddBuiltIn(int64_t x, int64_t y) {
211 const bool overflowed = __builtin_add_overflow(x, y, &result);
212 return overflowed ? cap : result;
215inline int64_t CapSubBuiltIn(int64_t x, int64_t y) {
218 const bool overflowed = __builtin_sub_overflow(x, y, &result);
219 return overflowed ? cap : result;
223inline int64_t CapProdBuiltIn(int64_t x, int64_t y) {
226 const bool overflowed = __builtin_mul_overflow(x, y, &result);
227 return overflowed ? cap : result;
265 const int kMaxBitIndexInInt64 = 63;
266 if (msb_sum <= kMaxBitIndexInInt64 - 2) return x * y;
269 if (a == 0 || b == 0) return 0;
271 if (msb_sum >= kMaxBitIndexInInt64) return cap;
275 const uint64_t u_prod = a * b;
281 if (u_prod >= static_cast<uint64_t>(cap)) return cap;
282 const int64_t abs_result = absl::bit_cast<int64_t>(u_prod);
292inline int64_t CapAdd(int64_t x, int64_t y) {
293#if defined(__GNUC__) && !defined(__clang__) && defined(__x86_64__)
315inline void CapAddTo(int64_t x, int64_t* y) { *y = CapAdd(*y, x); }
317inline int64_t CapSub(int64_t x, int64_t y) {
318#if defined(__GNUC__) && !defined(__clang__) && defined(__x86_64__)
328inline void CapSubFrom(int64_t amount, int64_t* target) {
329 *target = CapSub(*target, amount);
332inline int64_t CapProd(int64_t x, int64_t y) {
333#if defined(__GNUC__) && defined(__x86_64__)
348 static_assert(std::is_floating_point_v<T> || std::is_integral_v<T>);
349 if constexpr (std::is_integral_v<T>) {
350 if constexpr (std::is_same_v<T, int64_t>) {
354 std::is_same_v<T, int32_t>,
355 "CapOrFloatAdd() on integers only works for int and int64_t");
uint64_t uint_abs(int64_t n)
Definition saturated_arithmetic.h:246
int64_t SubOverflows(int64_t x, int64_t y)
Definition saturated_arithmetic.h:126
bool AtMinOrMaxInt64(int64_t x)
Definition saturated_arithmetic.h:53
bool AddHadOverflow(int64_t x, int64_t y, int64_t sum)
Definition saturated_arithmetic.h:98
int64_t CapAdd(int64_t x, int64_t y)
Definition saturated_arithmetic.h:292
void CapAddTo(int64_t x, int64_t *y)
Definition saturated_arithmetic.h:315
int64_t CapWithSignOf(int64_t x)
Definition saturated_arithmetic.h:143
int64_t TwosComplementAddition(int64_t x, int64_t y)
Definition saturated_arithmetic.h:82
int64_t CapSub(int64_t x, int64_t y)
Definition saturated_arithmetic.h:317
void CapSubFrom(int64_t amount, int64_t *target)
Definition saturated_arithmetic.h:328
bool AddIntoOverflow(int64_t x, int64_t *y)
Definition saturated_arithmetic.h:304
int64_t CapAddGeneric(int64_t x, int64_t y)
Definition saturated_arithmetic.h:233
T CapOrFloatAdd(T x, T y)
Definition saturated_arithmetic.h:347
bool AddOverflows(int64_t x, int64_t y)
Definition saturated_arithmetic.h:122
int64_t CapProd(int64_t x, int64_t y)
Definition saturated_arithmetic.h:332
bool SubHadOverflow(int64_t x, int64_t y, int64_t diff)
Definition saturated_arithmetic.h:107
int64_t TwosComplementSubtraction(int64_t x, int64_t y)
Definition saturated_arithmetic.h:89
int64_t CapAbs(int64_t v)
Definition saturated_arithmetic.h:61
int64_t CapProdGeneric(int64_t x, int64_t y)
Definition saturated_arithmetic.h:258
bool SafeAddInto(IntegerType a, IntegerType *b)
Definition saturated_arithmetic.h:133
int64_t CapSubGeneric(int64_t x, int64_t y)
Definition saturated_arithmetic.h:238
int64_t CapOpp(int64_t v)
Definition saturated_arithmetic.h:59
int MostSignificantBitPosition64(uint64_t n)
static const int32_t kint32min
static const int64_t kint64max
static const int32_t kint32max
static const int64_t kint64min