libcoyotl - A Library of C++ Tools

Created by Scott Robert Ladd at Coyote Gulch Productions.


realutil.h
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.