FougTools  0.7.0dev-046fb6a
Handy tools for C++, Qt and OpenCascade
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
utils.impl.h
Go to the documentation of this file.
1 /****************************************************************************
2 ** FougTools
3 ** Copyright Fougue (30 Mar. 2015)
4 ** contact@fougue.pro
5 **
6 ** This software is a computer program whose purpose is to provide utility
7 ** tools for the C++ language and the Qt toolkit.
8 **
9 ** This software is governed by the CeCILL-C license under French law and
10 ** abiding by the rules of distribution of free software. You can use,
11 ** modify and/ or redistribute the software under the terms of the CeCILL-C
12 ** license as circulated by CEA, CNRS and INRIA at the following URL
13 ** "http://www.cecill.info".
14 ****************************************************************************/
15 
16 #ifdef BITS_MATH_UTILS_H
17 
18 #include <cassert>
19 
20 // ---- Types Definitions
21 
22 
23 // ---- Comparison
24 
25 
26 template<typename T>
27 bool equalByAbsError(const T& a, const T& b, const T& tol)
28 {
29  assert(tol >= zero<T>() && "positive_tolerance");
30  return std::abs(a - b) <= tol;
31 }
32 
33 template<typename T>
34 bool equalByRelError(const T& a, const T& b,
35  const T& maxRelError,
36  const T& maxAbsError)
37 {
38  if (std::abs(a - b) < maxAbsError)
39  return true;
40  T relativeError;
41  if (std::abs(b) > std::abs(a))
42  relativeError = std::abs((a - b) / b);
43  else
44  relativeError = std::abs((a - b) / a);
45  if (relativeError <= maxRelError)
46  return true;
47  return false;
48 }
49 
50 template<typename T>
51 bool equalByIntDiff(const T& a, const T& b,
52  typename __impl::TypeTraits<T>::IntegralType_t maxDistInts,
53  ComparisonCheckFlags checkFlags)
54 {
55  typedef typename __impl::TypeTraits<T> Traits_t;
56  typedef typename __impl::TypeTraits<T>::IntegralType_t TraitsInt_t;
57 
58  assert(0 < maxDistInts && "positive_and_small_enough");
59 
60  // Comparison flags handling.
61  if ((checkFlags & NoCheck) == 0) {
62  /* if ((checkFlags & InfinityCheck) && (isInfinite(a) || isInfinite(b)))
63  {
64  // a and b are infinity (positive or negative) then only return true
65  // if they are exactly equal to each other that is, if they are
66  // both infinities of the same sign.
67  return a == b;
68  }
69  if ((checkFlags & NanCheck) && (isNan(a) || isNan(b)))
70  {
71  // If a or b is a NAN, return false. NANs are equal to nothing, not
72  // even themselves.
73  return false;
74  }*/
75  if ((checkFlags & SignCheck) && (sign(a) != sign(b))) {
76  // The check for a == b is used because zero and negative zero have
77  // different signs but are equal to each other.
78  return a == b;
79  }
80  }
81 
82  // Perform the general case comparison.
83  TraitsInt_t aAsInt = *(TraitsInt_t*)(&a);
84  if (aAsInt < 0) {
85  // Make aAsInt lexicographically ordered as a twos-complement int.
86  aAsInt = Traits_t::twoComplementValue() - aAsInt;
87  }
88  TraitsInt_t bAsInt = *(TraitsInt_t*)(&b);
89  if (bAsInt < 0) {
90  // Make bAsInt lexicographically ordered as a twos-complement int.
91  bAsInt = Traits_t::twoComplementValue() - bAsInt;
92  }
93  return std::abs(static_cast<double>(aAsInt - bAsInt)) <= maxDistInts;
94 }
95 
96 template<typename T>
97 T clamped(const T& v, const T& min, const T& max)
98 {
99  return v < min ? min : (v > max ? max : v);
100 }
101 
102 // ---- Conversion
103 
104 template<typename T>
105 double radianToDegree(const T& angle)
106 {
107  return (static_cast<double>(angle) * 180.) / math::pi;
108 }
109 
110 template<typename T>
111 double degreeToRadian(const T& angle)
112 {
113  return (math::pi * static_cast<double>(angle)) / 180.;
114 }
115 
116 // ---- Misceallenous
117 
118 template<typename T>
119 int sign(const T& v)
120 {
121  if (v == zero<T>())
122  return 0;
123  typedef typename __impl::TypeTraits<T> Traits_t;
124  typedef typename __impl::TypeTraits<T>::IntegralType_t TraitsInt_t;
125  if (Traits_t::isNativeIntegralType())
126  return v > 0 ? 1 : -1;
127  else
128  return ((*(TraitsInt_t*)&v) & Traits_t::twoComplementValue()) >= 0
129  ? 1 : -1;
130 }
131 
132 template<typename T>
133 T square(const T& x)
134 {
135  return x * x;
136 }
137 
138 template<typename T>
139 T zero()
140 {
141  return static_cast<T>(0);
142 }
143 
144 // ---- Status Report
145 
146 //
147 // /*! \brief Is the value \p v infinite ?
148 // * \todo Templatize this function.
149 // */
150 // const bool isInfinite(const float v)
151 // {
152 // const qint32 kInfAsInt = 0x7F800000;
153 // // An infinity has an exponent of 255 (shift left 23 positions) and
154 // // a zero mantissa. There are two infinities - positive and negative.
155 // return (*(qint32*)&v & 0x7FFFFFFF) == kInfAsInt;
156 // }
157 //
158 // /*! \brief Is the value \p v a NAN (Not A Number) ?
159 // * \todo Templatize this function.
160 // */
161 // const bool isNan(const float v)
162 // {
163 // // A NAN has an exponent of 255 (shifted left 23 positions) and
164 // // a non-zero mantissa.
165 // qint32 exp = *(qint32*) & v & 0x7F800000;
166 // qint32 mantissa = *(qint32*) & v & 0x007FFFFF;
167 // return exp == 0x7F800000 && mantissa != 0;
168 // }
169 
170 #endif // BITS_MATH_UTILS_H
double degreeToRadian(const T &angle)
int sign(const T &v)
Definition: utils.h:33
Definition: utils.h:30
T zero()
T clamped(const T &v, const T &min, const T &max)
T square(const T &x)
bool equalByIntDiff(const T &a, const T &b, typename __impl::TypeTraits< T >::IntegralType_t maxDistInts=10, ComparisonCheckFlags checkFlags=NoCheck)
const double pi
Definition: consts.h:20
bool equalByRelError(const T &a, const T &b, const T &maxRelError=static_cast< T >(1e-5), const T &maxAbsError=std::numeric_limits< T >::epsilon())
bool equalByAbsError(const T &a, const T &b, const T &tol=static_cast< T >(1e-6))
double radianToDegree(const T &angle)
ComparisonCheckFlags
Definition: utils.h:28