libcoyotl - A Library of C++ Tools

Created by Scott Robert Ladd at Coyote Gulch Productions.


realutil.h
1 //---------------------------------------------------------------------
2 // Algorithmic Conjurings @ http://www.coyotegulch.com
3 //
4 // realutil.h (libcoyotl)
5 //
6 // A collection of useful functions for working with numbers.
7 //---------------------------------------------------------------------
8 //
9 // Copyright 1990-2005 Scott Robert Ladd
10 //
11 // This program is free software; you can redistribute it and/or modify
12 // it under the terms of the GNU General Public License as published by
13 // the Free Software Foundation; either version 2 of the License, or
14 // (at your option) any later version.
15 //
16 // This program is distributed in the hope that it will be useful,
17 // but WITHOUT ANY WARRANTY; without even the implied warranty of
18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 // GNU General Public License for more details.
20 //
21 // You should have received a copy of the GNU General Public License
22 // along with this program; if not, write to the
23 // Free Software Foundation, Inc.
24 // 59 Temple Place - Suite 330
25 // Boston, MA 02111-1307, USA.
26 //
27 //-----------------------------------------------------------------------
28 //
29 // For more information on this software package, please visit
30 // Scott's web site, Coyote Gulch Productions, at:
31 //
32 // http://www.coyotegulch.com
33 //
34 //-----------------------------------------------------------------------
35 
36 #if !defined(LIBCOYOTL_REALUTIL_H)
37 #define LIBCOYOTL_REALUTIL_H
38 
39 #include <cstddef>
40 #include <cmath>
41 #include <limits>
42 
43 namespace libcoyotl
44 {
46 
50  template <typename T>
51  T round_nearest(T x)
52  {
53  T result, fraction, dummy;
54 
55  fraction = fabs(modf(x,&result));
56 
57  if (fraction == T(0.0))
58  return result;
59 
60  if (fraction == T(0.5))
61  {
62  if (modf(result / T(2.0), &dummy) != T(0.0))
63  {
64  if (x < T(0.0))
65  result -= T(1.0);
66  else
67  result += T(1.0);
68  }
69  }
70  else
71  {
72  if (fraction > T(0.5))
73  {
74  if (x < T(0.0))
75  result -= T(1.0);
76  else
77  result += T(1.0);
78  }
79  }
80 
81  return result;
82  }
83 
84  // Set number of significant digits in a floating-point value
92  template <typename T>
93  T sigdig(T x, unsigned short n)
94  {
95  T scale_factor, result;
96 
97  // is asking for no digits, or more digits than in double, simply return x
98  if ((n == 0) || (n > std::numeric_limits<T>::digits10))
99  result = x;
100  else
101  {
102  // find a factor of ten such that all significant digits will
103  // be in the integer part of the double
104  scale_factor = pow(T(10.0),T((int)n - 1 - (int)floor(log10(fabs(x)))));
105 
106  // scale up, round, and scale down
107  result = round_nearest(x * scale_factor) / scale_factor;
108  }
109 
110  return result;
111  }
112 
114 
128  template <typename T>
129  bool are_equal(T a, T b, T tolerance = T(1.0))
130  {
131  // find the range of tolerance
132  T adjustment = tolerance * std::numeric_limits<T>::epsilon();
133 
134  // set high and low bounds on a's value
135  T low = b - adjustment;
136  T hi = b + adjustment;
137 
138  // compare a to range
139  return ((a >= low) && (a <= hi));
140  }
141 
142  // Lowest common multiple
146  unsigned long lcm(unsigned long x, unsigned long y);
147 
148  // Greatest common denominator
152  unsigned long gcd(unsigned long x, unsigned long y);
153 
155 
158  template <class T> inline T abs_val(T value)
159  {
160  return (value < 0 ? (-value) : value);
161  }
162 
164 
167  inline unsigned long abs_val(unsigned long value)
168  {
169  return value;
170  }
171 
173 
176  inline unsigned int abs_val(unsigned int value)
177  {
178  return value;
179  }
180 
182 
185  inline unsigned short abs_val(unsigned short value)
186  {
187  return value;
188  }
189 
191 
194  inline unsigned char abs_val(unsigned char value)
195  {
196  return value;
197  }
198 
200 
203  template <class T> inline T min_of(T x1,T x2)
204  {
205  return (x1 < x2 ? x1 : x2);
206  }
207 
209 
212  template <class T> inline T max_of(T x1,T x2)
213  {
214  return (x1 > x2 ? x1 : x2);
215  }
216 
218 
221  inline double asinh(const double& x)
222  {
223  return log(x + sqrt(x * x + 1.0));
224  }
225 
227 
230  inline double acosh(const double& x)
231  {
232  return log(x + sqrt(x * x - 1.0));
233  }
234 
236 
239  inline double atanh(const double& x)
240  {
241  return log((1.0 + x) / (1.0 - x)) / 2.0;
242  }
243 
244 } // end namespace libcoyotl
245 
246 #endif

© 1996-2005 Scott Robert Ladd. All rights reserved.
HTML documentation generated by Dimitri van Heesch's excellent Doxygen tool.