22 #ifndef OR_TOOLS_UTIL_FP_UTILS_H_
23 #define OR_TOOLS_UTIL_FP_UTILS_H_
26 #pragma fenv_access(on)
32 #include <xmmintrin.h>
46 static inline double isnan(
double value) {
return _isnan(
value); }
47 static inline double round(
double value) {
return floor(
value + 0.5); }
48 #elif defined(__APPLE__) || __GNUC__ >= 5
69 #elif (defined(__GNUC__) || defined(__llvm__)) && defined(__x86_64__)
70 CHECK_EQ(0, fegetenv(&saved_fenv_));
77 #elif defined(__x86_64__) && defined(__GLIBC__)
78 CHECK_EQ(0, fesetenv(&saved_fenv_));
85 #elif (defined(__GNUC__) || defined(__llvm__)) && defined(__x86_64__) && \
87 CHECK_EQ(0, fegetenv(&fenv_));
88 excepts &= FE_ALL_EXCEPT;
89 #if defined(__APPLE__)
90 fenv_.__control &= ~excepts;
91 #elif defined(__FreeBSD__)
92 fenv_.__x87.__control &= ~excepts;
94 fenv_.__control_word &= ~excepts;
96 fenv_.__mxcsr &= ~(excepts << 7);
97 CHECK_EQ(0, fesetenv(&fenv_));
102 #if defined(_MSC_VER)
104 #elif (defined(__GNUC__) || defined(__llvm__)) && defined(__x86_64__)
106 mutable fenv_t saved_fenv_;
110 template <
typename FloatType>
112 return x == std::numeric_limits<FloatType>::infinity() ||
113 x == -std::numeric_limits<FloatType>::infinity();
123 template <
typename FloatType>
125 FloatType relative_tolerance,
126 FloatType absolute_tolerance) {
127 DCHECK_LE(0.0, relative_tolerance);
128 DCHECK_LE(0.0, absolute_tolerance);
129 DCHECK_GT(1.0, relative_tolerance);
133 const FloatType difference = fabs(x - y);
134 if (difference <= absolute_tolerance) {
137 const FloatType largest_magnitude =
std::max(fabs(x), fabs(y));
138 return difference <= largest_magnitude * relative_tolerance;
144 template <
typename FloatType>
146 FloatType absolute_tolerance) {
147 DCHECK_LE(0.0, absolute_tolerance);
151 return fabs(x - y) <= absolute_tolerance;
156 template <
typename FloatType>
159 return x <= y + tolerance *
std::max(1.0,
std::min(std::abs(x), std::abs(y)));
164 template <
typename FloatType>
166 DCHECK_LE(0.0, tolerance);
168 return std::abs(x - std::round(x)) <= tolerance;
174 #define EXPECT_COMPARABLE(expected, obtained, epsilon) \
175 EXPECT_TRUE(operations_research::AreWithinAbsoluteOrRelativeTolerances( \
176 expected, obtained, epsilon, epsilon)) \
177 << obtained << " != expected value " << expected \
178 << " within epsilon = " << epsilon;
180 #define EXPECT_NOTCOMPARABLE(expected, obtained, epsilon) \
181 EXPECT_FALSE(operations_research::AreWithinAbsoluteOrRelativeTolerances( \
182 expected, obtained, epsilon, epsilon)) \
183 << obtained << " == expected value " << expected \
184 << " within epsilon = " << epsilon;
210 int64_t max_absolute_sum,
211 double* scaling_factor,
219 const std::vector<double>& lb,
220 const std::vector<double>& ub,
221 int64_t max_absolute_sum);
231 const std::vector<double>& lb,
232 const std::vector<double>& ub,
233 const double scaling_factor,
235 double* max_scaled_sum_error);
242 double scaling_factor);
245 template <
typename FloatType>
246 inline FloatType
Interpolate(FloatType x, FloatType y, FloatType alpha) {
247 return alpha * x + (1 - alpha) * y;
void EnableExceptions(int excepts)
~ScopedFloatingPointEnv()
Collection of objects used to extend the Constraint Solver library.
int fast_ilogb(double value)
bool IsSmallerWithinTolerance(FloatType x, FloatType y, FloatType tolerance)
bool IsIntegerWithinTolerance(FloatType x, FloatType tolerance)
FloatType Interpolate(FloatType x, FloatType y, FloatType alpha)
bool AreWithinAbsoluteOrRelativeTolerances(FloatType x, FloatType y, FloatType relative_tolerance, FloatType absolute_tolerance)
void ComputeScalingErrors(const std::vector< double > &input, const std::vector< double > &lb, const std::vector< double > &ub, double scaling_factor, double *max_relative_coeff_error, double *max_scaled_sum_error)
double fast_scalbn(double value, int exponent)
void fast_scalbn_inplace(double &mutable_value, int exponent)
bool AreWithinAbsoluteTolerance(FloatType x, FloatType y, FloatType absolute_tolerance)
int64_t ComputeGcdOfRoundedDoubles(const std::vector< double > &x, double scaling_factor)
double GetBestScalingOfDoublesToInt64(const std::vector< double > &input, const std::vector< double > &lb, const std::vector< double > &ub, int64_t max_absolute_sum)
bool IsPositiveOrNegativeInfinity(FloatType x)
static int input(yyscan_t yyscanner)
double max_relative_coeff_error