Gnash  0.8.11dev
GnashNumeric.h
Go to the documentation of this file.
1 // GnashNumeric.h: vaguely useful mathematical functions.
2 //
3 // Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
4 // Free Software Foundation, Inc
5 //
6 // This program is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 3 of the License, or
9 // (at your option) any later version.
10 //
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software
18 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 //
20 
21 #ifndef GNASH_NUMERIC_H
22 #define GNASH_NUMERIC_H
23 
24 #ifdef HAVE_CONFIG_H
25 # include "gnashconfig.h"
26 #endif
27 
28 #ifdef SOLARIS_HOST
29 # include <ieeefp.h> // for finite()
30 #endif
31 
32 #include <cassert>
33 #include <cmath>
34 #include <algorithm>
35 #include <boost/cstdint.hpp>
36 #include <limits>
37 #include <boost/utility/enable_if.hpp>
38 #include <boost/type_traits/is_floating_point.hpp>
39 
40 namespace gnash {
41 
42 // Using a possible built-in pi constant M_PI, which is not in
43 // the C++ standard, has no greate advantage, so we will use this
44 // one. Make it as accurate as you like.
45 static const double PI = 3.14159265358979323846;
46 
47 inline bool
48 isFinite(double d)
49 {
50 #if defined(HAVE_FINITE) && !defined(HAVE_ISFINITE)
51  return (finite(d));
52 #else
53  // Put using namespace std; here if you have to
54  // put it anywhere.
55  using namespace std;
56  return (isfinite(d));
57 #endif
58 }
59 
60 template <typename T>
61 inline
62 typename boost::enable_if<boost::is_floating_point<T>, bool>::type
63 isNaN(const T& num)
64 {
65  return num != num;
66 }
67 
68 inline double
70 {
71  return isFinite(x) ? x : 0.0;
72 }
73 
74 template <typename T>
75 inline T
76 clamp(T i, T min, T max)
77 {
78  assert(min <= max);
79  return std::max<T>(min, std::min<T>(i, max));
80 }
81 
82 template<typename T>
83 inline T
84 lerp(T a, T b, T f)
85 {
86  return (b - a) * f + a;
87 }
88 
89 inline int
90 frnd(float f)
91 {
92  return static_cast<int>(f + 0.5f);
93 }
94 
95 inline double
97 {
98  return i / 20.0;
99 }
100 
101 template<size_t Factor>
102 boost::int32_t
104 {
105  // If a is NaN, then this function would return -NAN, which when cast to
106  // int32, converts to zero on x86*, but converts to -1 on ARM. The
107  // behaviour is undefined according to ISO-IEC 14882:2003 4.9.1.
108  if (isNaN(a)) {
109  return 0;
110  }
111 
112  const double factor = static_cast<double>(Factor);
113 
114  // This truncates large values without relying on undefined behaviour.
115  // For very large values of 'a' it is noticeably slower than the UB
116  // version (due to fmod), but should always be legal behaviour. For
117  // ordinary values (within ±1.07374e+08 pixels) it is comparable to
118  // the UB version for speed. Because values outside the limit are
119  // extremely rare, using this safe version has no implications for
120  // performance under normal circumstances.
121  static const double upperUnsignedLimit =
122  std::numeric_limits<boost::uint32_t>::max() + 1.0;
123  static const double upperSignedLimit =
124  std::numeric_limits<boost::int32_t>::max() / factor;
125  static const double lowerSignedLimit =
126  std::numeric_limits<boost::int32_t>::min() / factor;
127 
128  if (a >= lowerSignedLimit && a <= upperSignedLimit) {
129  return a * Factor;
130  }
131 
132  // This slow truncation happens only in very unlikely cases.
133  return a >= 0 ?
134  static_cast<boost::uint32_t>(
135  std::fmod(a * factor, upperUnsignedLimit))
136  :
137  -static_cast<boost::uint32_t>(
138  std::fmod(-a * factor, upperUnsignedLimit));
139 }
140 
141 // truncate when overflow occurs.
142 inline boost::int32_t
144 {
145  return truncateWithFactor<20>(a);
146 }
147 
148 } // namespace gnash
149 
150 #endif
Definition: GnashKey.h:147
Definition: GnashKey.h:150
double infinite_to_zero(double x)
Definition: GnashNumeric.h:69
double twipsToPixels(int i)
Definition: GnashNumeric.h:96
type
Definition: GnashKey.h:329
Definition: GnashKey.h:152
boost::int32_t truncateWithFactor(double a)
Definition: GnashNumeric.h:103
T lerp(T a, T b, T f)
Definition: GnashNumeric.h:84
bool isFinite(double d)
Definition: GnashNumeric.h:48
boost::enable_if< boost::is_floating_point< T >, bool >::type isNaN(const T &num)
Definition: GnashNumeric.h:63
boost::int32_t x
Definition: BitmapData_as.cpp:434
Definition: GnashKey.h:148
T clamp(T i, T min, T max)
Definition: GnashNumeric.h:76
int frnd(float f)
Definition: GnashNumeric.h:90
Definition: GnashKey.h:132
Definition: GnashKey.h:155
boost::int32_t pixelsToTwips(double a)
Definition: GnashNumeric.h:143