• Main Page
  • Related Pages
  • Namespaces
  • Classes
  • Files
  • Examples
  • File List
  • File Members

GnashNumeric.h

Go to the documentation of this file.
00001 // GnashNumeric.h: vaguely useful mathematical functions.
00002 // 
00003 //   Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Free Software
00004 //   Foundation, Inc
00005 // 
00006 // This program is free software; you can redistribute it and/or modify
00007 // it under the terms of the GNU General Public License as published by
00008 // the Free Software Foundation; either version 3 of the License, or
00009 // (at your option) any later version.
00010 // 
00011 // This program is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 // GNU General Public License for more details.
00015 // 
00016 // You should have received a copy of the GNU General Public License
00017 // along with this program; if not, write to the Free Software
00018 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00019 //
00020 
00021 #ifndef GNASH_NUMERIC_H
00022 #define GNASH_NUMERIC_H
00023 
00024 #ifdef HAVE_CONFIG_H
00025 # include "gnashconfig.h"
00026 #endif
00027 
00028 #ifdef SOLARIS_HOST
00029 # include <ieeefp.h> // for finite()
00030 #endif
00031 
00032 #include <cmath>
00033 #include <algorithm>
00034 #include <boost/cstdint.hpp>
00035 #include <limits>
00036 
00037 namespace gnash {
00038 
00039 // Using a possible built-in pi constant M_PI, which is not in
00040 // the C++ standard, has no greate advantage, so we will use this
00041 // one. Make it as accurate as you like.
00042 static const double PI = 3.14159265358979323846;
00043 
00044 inline bool
00045 isFinite(double d)
00046 {
00047 #if defined(HAVE_FINITE) && !defined(HAVE_ISFINITE)
00048     return (finite(d));
00049 #else
00050     // Put using namespace std; here if you have to
00051     // put it anywhere.
00052     using namespace std;
00053     return (isfinite(d));
00054 #endif
00055 }
00056 
00057 inline double
00058 infinite_to_zero(double x)
00059 {
00060     return isFinite(x) ? x : 0.0;
00061 }
00062 
00063 template <typename T>
00064 inline T
00065 clamp(T i, T min, T max)
00066 {
00067         assert(min <= max);
00068         return std::max<T>(min, std::min<T>(i, max));
00069 }
00070 
00071 template<typename T>
00072 inline T
00073 lerp(T a, T b, T f)
00074 {
00075     return (b - a) * f + a;
00076 }
00077 
00078 inline int
00079 frnd(float f) 
00080 {
00081     return static_cast<int>(f + 0.5f);
00082 }
00083 
00084 inline double
00085 twipsToPixels(int i) 
00086 { 
00087     return static_cast<double>(i / 20.0); 
00088 }
00089 
00090 template<size_t Factor>
00091 boost::int32_t
00092 truncateWithFactor(double a)
00093 { 
00094 
00095     const double factor = static_cast<double>(Factor);
00096 
00097     // This truncates large values without relying on undefined behaviour.
00098     // For very large values of 'a' it is noticeably slower than the UB
00099     // version (due to fmod), but should always be legal behaviour. For
00100     // ordinary values (within ±1.07374e+08 pixels) it is comparable to
00101     // the UB version for speed. Because values outside the limit are
00102     // extremely rare, using this safe version has no implications for
00103     // performance under normal circumstances.
00104     static const double upperUnsignedLimit =
00105                 std::numeric_limits<boost::uint32_t>::max() + 1.0;
00106     static const double upperSignedLimit =
00107                 std::numeric_limits<boost::int32_t>::max() / factor;
00108     static const double lowerSignedLimit =
00109                 std::numeric_limits<boost::int32_t>::min() / factor;
00110 
00111     if (a >= lowerSignedLimit && a <= upperSignedLimit) {
00112         return static_cast<boost::int32_t>(a * factor);
00113     }
00114 
00115     // This slow truncation happens only in very unlikely cases.
00116     return a >= 0 ?
00117         static_cast<boost::uint32_t>(
00118                 std::fmod(a * factor, upperUnsignedLimit))
00119         : 
00120         -static_cast<boost::uint32_t>(
00121                 std::fmod(-a * factor, upperUnsignedLimit));
00122 }
00123 
00124 // truncate when overflow occurs.
00125 inline boost::int32_t
00126 pixelsToTwips(double a)
00127 {
00128     return truncateWithFactor<20>(a);
00129 }
00130 
00131 } // namespace gnash
00132 
00133 #endif

Generated on Fri Mar 16 2012 15:46:10 for Gnash by  doxygen 1.7.1