14#ifndef OR_TOOLS_BASE_MATHUTIL_H_
15#define OR_TOOLS_BASE_MATHUTIL_H_
25#include "absl/base/casts.h"
39 template <
typename IntegralType>
41 IntegralType denominator) {
42 DCHECK_NE(0, denominator);
43 const IntegralType rounded_toward_zero = numerator / denominator;
44 const IntegralType intermediate_product = rounded_toward_zero * denominator;
45 const bool needs_adjustment =
46 (rounded_toward_zero >= 0) &&
47 ((denominator > 0 && numerator > intermediate_product) ||
48 (denominator < 0 && numerator < intermediate_product));
49 const IntegralType adjustment =
static_cast<IntegralType
>(needs_adjustment);
50 const IntegralType ceil_of_ratio = rounded_toward_zero + adjustment;
53 template <
typename IntegralType>
55 IntegralType denominator) {
56 DCHECK_NE(0, denominator);
57 const IntegralType rounded_toward_zero = numerator / denominator;
58 const IntegralType intermediate_product = rounded_toward_zero * denominator;
59 const bool needs_adjustment =
60 (rounded_toward_zero <= 0) &&
61 ((denominator > 0 && numerator < intermediate_product) ||
62 (denominator < 0 && numerator > intermediate_product));
63 const IntegralType adjustment =
static_cast<IntegralType
>(needs_adjustment);
64 const IntegralType floor_of_ratio = rounded_toward_zero - adjustment;
65 return floor_of_ratio;
69 static unsigned int GCD(
unsigned int x,
unsigned int y) {
71 unsigned int r = x % y;
96 static T
Abs(
const T x) {
97 return x > 0 ? x : -x;
101 template <
typename T>
108 static int64_t
GCD64(int64_t x, int64_t y) {
119 template <
typename T>
121 return pow(
base, exp);
124 template <
class IntOut,
class FloatIn>
130 if (x > -0.5 && x < 0.5) {
134 return static_cast<IntOut
>(0);
136 return static_cast<IntOut
>(x < 0 ? (x - 0.5) : (x + 0.5));
143 template <
typename IntType>
144 static IntType
RoundUpTo(IntType input_value, IntType rounding_value) {
145 static_assert(std::numeric_limits<IntType>::is_integer,
146 "RoundUpTo() operation type is not integer");
147 DCHECK_GE(input_value, 0);
148 DCHECK_GT(rounding_value, 0);
149 const IntType remainder = input_value % rounding_value;
150 return (remainder == 0) ? input_value
151 : (input_value - remainder + rounding_value);
174 template <
class IntOut,
class FloatIn>
179 IntOut_is_not_integer);
180 COMPILE_ASSERT(std::numeric_limits<IntOut>::radix == 2, IntOut_is_base_2);
188 if (!std::numeric_limits<IntOut>::is_signed && x < 0) {
194 return x < 0 ? std::numeric_limits<IntOut>::lowest()
195 : std::numeric_limits<IntOut>::max();
209 if (exp <= std::numeric_limits<IntOut>::digits) {
214 return x < 0 ? std::numeric_limits<IntOut>::lowest()
215 : std::numeric_limits<IntOut>::max();
231 template <
class IntOut,
class FloatIn>
236 IntOut_is_not_integer);
322 template <
typename T>
324 static_assert(std::is_arithmetic_v<T>);
325 if constexpr (std::numeric_limits<T>::is_integer) {
331 if (std::abs(x) <= 1e-6 && std::abs(y) <= 1e-6)
return true;
332 if (std::abs(x - y) <= 1e-6)
return true;
333 return std::abs(x - y) / std::max(std::abs(x), std::abs(y)) <= 1e-6;
static double Stirling(double n)
static T Square(const T x)
Returns the square of x.
static T IPow(T base, int exp)
static IntOut SafeRound(FloatIn x)
static IntType RoundUpTo(IntType input_value, IntType rounding_value)
static IntOut Round(FloatIn x)
static int64_t FastInt64Round(double x)
static unsigned int LeastCommonMultiple(unsigned int a, unsigned int b)
static unsigned int GCD(unsigned int x, unsigned int y)
Returns the greatest common divisor of two unsigned integers x and y.
static double LogCombinations(int n, int k)
static int64_t GCD64(int64_t x, int64_t y)
static IntegralType CeilOfRatio(IntegralType numerator, IntegralType denominator)
static IntegralType FloorOfRatio(IntegralType numerator, IntegralType denominator)
static IntOut SafeCast(FloatIn x)
static bool AlmostEquals(const T x, const T y)
#define COMPILE_ASSERT(x, msg)
In SWIG mode, we don't want anything besides these top-level includes.