7 #ifndef UTIL_MATH_MATHUTIL_H__ 8 #define UTIL_MATH_MATHUTIL_H__ 14 #include "base/casts.h" 15 #include "base/integral_types.h" 16 #include "base/logging.h" 17 #include "base/macros.h" 18 #include "util/math/mathlimits.h" 54 static int32 FastIntRound(
double x) {
60 #if defined __GNUC__ && (defined __i386__ || defined __SSE2__) 69 #elif defined __i386__ 78 #endif // if defined __x86_64__ || ... 80 return Round<int32, double>(x);
81 #endif // if defined __GNUC__ && ... 84 static int64 FastInt64Round(
double x) {
85 #if defined __GNUC__ && (defined __i386__ || defined __x86_64__) 86 #if defined __x86_64__ 94 #elif defined __i386__ 104 #endif // if defined __i386__ 106 return Round<int64, double>(x);
107 #endif // if defined __GNUC__ && ... 116 static double Harmonic(int64 n,
double *e);
120 static double Stirling(
double n);
127 static double LogCombinations(
int n,
int k);
137 static float RoundOffBits(
const float f,
const int bits) {
138 const int32 f_rep = bit_cast<int32>(f);
141 int32 g_rep = f_rep & ~((1 << bits) - 1);
145 const int32 lowbits = f_rep & ((1 << bits) - 1);
146 if (lowbits > (1 << (bits - 1)) ||
147 (lowbits == (1 << (bits - 1)) && (f_rep & (1 << bits)))) {
148 g_rep += (1 << bits);
154 return bit_cast<float>(g_rep);
157 static double RoundOffBits(
const double f,
const int bits) {
158 const int64 f_rep = bit_cast<int64>(f);
159 int64 g_rep = f_rep & ~((1LL << bits) - 1);
160 const int64 lowbits = f_rep & ((1LL << bits) - 1);
161 if (lowbits > (1LL << (bits - 1)) ||
162 (lowbits == (1LL << (bits - 1)) && (f_rep & (1LL << bits)))) {
163 g_rep += (1LL << bits);
165 return bit_cast<double>(g_rep);
175 static T Max(
const T x,
const T y) {
184 static T Min(
const T x,
const T y) {
194 static T Abs(
const T x) {
195 return x > 0 ? x : -x;
201 static typename MathLimits<T>::UnsignedType AbsDiff(
const T x,
const T y) {
203 typedef typename MathLimits<T>::UnsignedType R;
204 return x > y ? R(x) - R(y) : R(y) - R(x);
214 static T Sign(
const T x) {
237 static bool WithinMargin(
const T x,
const T y,
const T margin) {
238 DCHECK_GE(margin, 0);
240 return AbsDiff(x, y) <= margin;
250 static bool WithinFraction(
const T x,
const T y,
const T fraction);
259 static bool WithinFractionOrMargin(
const T x,
const T y,
260 const T fraction,
const T margin);
268 static bool NearByMargin(
const T x,
const T y) {
275 static bool NearByFraction(
const T x,
const T y) {
283 static bool NearByFractionOrMargin(
const T x,
const T y) {
331 static bool AlmostEquals(
const T x,
const T y) {
341 return MathUtil::NearByFractionOrMargin<T>(x, y);
346 static const T& Clamp(
const T& low,
const T& high,
const T& value) {
347 return std::max(low, std::min(value, high));
352 static void ClampValue(
const T& low,
const T& high, T* value) {
353 *value = Clamp(low, high, *value);
358 bool MathUtil::WithinFraction(
const T x,
const T y,
const T fraction) {
360 DCHECK((0 < fraction || 0 == fraction) && fraction < 1);
371 (AbsDiff(x, y) <= fraction * Max(Abs(x), Abs(y)));
376 bool MathUtil::WithinFractionOrMargin(
const T x,
const T y,
377 const T fraction,
const T margin) {
379 DCHECK((0 < fraction || 0 == fraction) && fraction < 1 && margin >= 0);
390 (AbsDiff(x, y) <= Max(margin, fraction * Max(Abs(x), Abs(y))));
394 #endif // UTIL_MATH_MATHUTIL_H__