22 #ifndef OR_TOOLS_UTIL_FP_UTILS_H_
23 #define OR_TOOLS_UTIL_FP_UTILS_H_
26 #pragma fenv_access(on) // NOLINT
32 #include <xmmintrin.h>
42 static inline double isnan(
double value) {
return _isnan(
value); }
43 static inline double round(
double value) {
return floor(
value + 0.5); }
44 #elif defined(__APPLE__) || __GNUC__ >= 5
65 #elif defined(ARCH_K8)
66 CHECK_EQ(0, fegetenv(&saved_fenv_));
73 #elif defined(ARCH_K8)
74 CHECK_EQ(0, fesetenv(&saved_fenv_));
81 #elif defined(ARCH_K8)
82 CHECK_EQ(0, fegetenv(&fenv_));
83 excepts &= FE_ALL_EXCEPT;
84 #if defined(__APPLE__)
85 fenv_.__control &= ~excepts;
86 #elif defined(__FreeBSD__)
87 fenv_.__x87.__control &= ~excepts;
89 fenv_.__control_word &= ~excepts;
91 fenv_.__mxcsr &= ~(excepts << 7);
92 CHECK_EQ(0, fesetenv(&fenv_));
99 #elif defined(ARCH_K8)
101 mutable fenv_t saved_fenv_;
105 template <
typename FloatType>
107 return x == std::numeric_limits<FloatType>::infinity() ||
108 x == -std::numeric_limits<FloatType>::infinity();
118 template <
typename FloatType>
120 FloatType relative_tolerance,
121 FloatType absolute_tolerance) {
122 DCHECK_LE(0.0, relative_tolerance);
123 DCHECK_LE(0.0, absolute_tolerance);
124 DCHECK_GT(1.0, relative_tolerance);
128 const FloatType difference = fabs(x - y);
129 if (difference <= absolute_tolerance) {
132 const FloatType largest_magnitude =
std::max(fabs(x), fabs(y));
133 return difference <= largest_magnitude * relative_tolerance;
139 template <
typename FloatType>
141 FloatType absolute_tolerance) {
142 DCHECK_LE(0.0, absolute_tolerance);
146 return fabs(x - y) <= absolute_tolerance;
151 template <
typename FloatType>
154 return x <= y + tolerance *
std::max(1.0,
std::min(std::abs(x), std::abs(y)));
159 template <
typename FloatType>
161 DCHECK_LE(0.0, tolerance);
163 return std::abs(x - std::round(x)) <= tolerance;
169 #define EXPECT_COMPARABLE(expected, obtained, epsilon) \
170 EXPECT_TRUE(operations_research::AreWithinAbsoluteOrRelativeTolerances( \
171 expected, obtained, epsilon, epsilon)) \
172 << obtained << " != expected value " << expected \
173 << " within epsilon = " << epsilon;
175 #define EXPECT_NOTCOMPARABLE(expected, obtained, epsilon) \
176 EXPECT_FALSE(operations_research::AreWithinAbsoluteOrRelativeTolerances( \
177 expected, obtained, epsilon, epsilon)) \
178 << obtained << " == expected value " << expected \
179 << " within epsilon = " << epsilon;
205 int64 max_absolute_sum,
206 double* scaling_factor,
214 const std::vector<double>& lb,
215 const std::vector<double>& ub,
216 int64 max_absolute_sum);
226 const std::vector<double>& lb,
227 const std::vector<double>& ub,
228 const double scaling_factor,
230 double* max_scaled_sum_error);
237 double scaling_factor);
240 template <
typename FloatType>
241 inline FloatType
Interpolate(FloatType x, FloatType y, FloatType alpha) {
242 return alpha * x + (1 - alpha) * y;
247 #endif // OR_TOOLS_UTIL_FP_UTILS_H_