Created by Scott Robert Ladd at Coyote Gulch Productions.
00001 //--------------------------------------------------------------------- 00002 // Algorithmic Conjurings @ http://www.coyotegulch.com 00003 // 00004 // realutil.h (libcoyotl) 00005 // 00006 // A collection of useful functions for working with numbers. 00007 //--------------------------------------------------------------------- 00008 // 00009 // Copyright 1990-2005 Scott Robert Ladd 00010 // 00011 // This program is free software; you can redistribute it and/or modify 00012 // it under the terms of the GNU General Public License as published by 00013 // the Free Software Foundation; either version 2 of the License, or 00014 // (at your option) any later version. 00015 // 00016 // This program is distributed in the hope that it will be useful, 00017 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 // GNU General Public License for more details. 00020 // 00021 // You should have received a copy of the GNU General Public License 00022 // along with this program; if not, write to the 00023 // Free Software Foundation, Inc. 00024 // 59 Temple Place - Suite 330 00025 // Boston, MA 02111-1307, USA. 00026 // 00027 //----------------------------------------------------------------------- 00028 // 00029 // For more information on this software package, please visit 00030 // Scott's web site, Coyote Gulch Productions, at: 00031 // 00032 // http://www.coyotegulch.com 00033 // 00034 //----------------------------------------------------------------------- 00035 00036 #if !defined(LIBCOYOTL_REALUTIL_H) 00037 #define LIBCOYOTL_REALUTIL_H 00038 00039 #include <cstddef> 00040 #include <cmath> 00041 #include <limits> 00042 00043 namespace libcoyotl 00044 { 00046 00050 template <typename T> 00051 T round_nearest(T x) 00052 { 00053 T result, fraction, dummy; 00054 00055 fraction = fabs(modf(x,&result)); 00056 00057 if (fraction == T(0.0)) 00058 return result; 00059 00060 if (fraction == T(0.5)) 00061 { 00062 if (modf(result / T(2.0), &dummy) != T(0.0)) 00063 { 00064 if (x < T(0.0)) 00065 result -= T(1.0); 00066 else 00067 result += T(1.0); 00068 } 00069 } 00070 else 00071 { 00072 if (fraction > T(0.5)) 00073 { 00074 if (x < T(0.0)) 00075 result -= T(1.0); 00076 else 00077 result += T(1.0); 00078 } 00079 } 00080 00081 return result; 00082 } 00083 00084 // Set number of significant digits in a floating-point value 00092 template <typename T> 00093 T sigdig(T x, unsigned short n) 00094 { 00095 T scale_factor, result; 00096 00097 // is asking for no digits, or more digits than in double, simply return x 00098 if ((n == 0) || (n > std::numeric_limits<T>::digits10)) 00099 result = x; 00100 else 00101 { 00102 // find a factor of ten such that all significant digits will 00103 // be in the integer part of the double 00104 scale_factor = pow(T(10.0),T((int)n - 1 - (int)floor(log10(fabs(x))))); 00105 00106 // scale up, round, and scale down 00107 result = round_nearest(x * scale_factor) / scale_factor; 00108 } 00109 00110 return result; 00111 } 00112 00114 00128 template <typename T> 00129 bool are_equal(T a, T b, T tolerance = T(1.0)) 00130 { 00131 // find the range of tolerance 00132 T adjustment = tolerance * std::numeric_limits<T>::epsilon(); 00133 00134 // set high and low bounds on a's value 00135 T low = b - adjustment; 00136 T hi = b + adjustment; 00137 00138 // compare a to range 00139 return ((a >= low) && (a <= hi)); 00140 } 00141 00142 // Lowest common multiple 00146 unsigned long lcm(unsigned long x, unsigned long y); 00147 00148 // Greatest common denominator 00152 unsigned long gcd(unsigned long x, unsigned long y); 00153 00155 00158 template <class T> inline T abs_val(T value) 00159 { 00160 return (value < 0 ? (-value) : value); 00161 } 00162 00164 00167 inline unsigned long abs_val(unsigned long value) 00168 { 00169 return value; 00170 } 00171 00173 00176 inline unsigned int abs_val(unsigned int value) 00177 { 00178 return value; 00179 } 00180 00182 00185 inline unsigned short abs_val(unsigned short value) 00186 { 00187 return value; 00188 } 00189 00191 00194 inline unsigned char abs_val(unsigned char value) 00195 { 00196 return value; 00197 } 00198 00200 00203 template <class T> inline T min_of(T x1,T x2) 00204 { 00205 return (x1 < x2 ? x1 : x2); 00206 } 00207 00209 00212 template <class T> inline T max_of(T x1,T x2) 00213 { 00214 return (x1 > x2 ? x1 : x2); 00215 } 00216 00218 00221 inline double asinh(const double& x) 00222 { 00223 return log(x + sqrt(x * x + 1.0)); 00224 } 00225 00227 00230 inline double acosh(const double& x) 00231 { 00232 return log(x + sqrt(x * x - 1.0)); 00233 } 00234 00236 00239 inline double atanh(const double& x) 00240 { 00241 return log((1.0 + x) / (1.0 - x)) / 2.0; 00242 } 00243 00244 } // end namespace libcoyotl 00245 00246 #endif
© 1996-2005 Scott Robert Ladd. All rights reserved.
HTML documentation generated by Dimitri van Heesch's excellent Doxygen tool.