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
43namespace 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.