Avoid appending null byte to RTMP method name.
[gnash.git] / libbase / GnashNumeric.h
blobfb4f0293960bbc23f490bf031066142f09dcab9e
1 // GnashNumeric.h: vaguely useful mathematical functions.
2 //
3 // Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Free Software
4 // 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
21 #ifndef GNASH_NUMERIC_H
22 #define GNASH_NUMERIC_H
24 #ifdef HAVE_CONFIG_H
25 # include "gnashconfig.h"
26 #endif
28 #ifdef SOLARIS_HOST
29 # include <ieeefp.h> // for finite()
30 #endif
32 #include <cassert>
33 #include <cmath>
34 #include <algorithm>
35 #include <boost/cstdint.hpp>
36 #include <limits>
38 namespace gnash {
40 // Using a possible built-in pi constant M_PI, which is not in
41 // the C++ standard, has no greate advantage, so we will use this
42 // one. Make it as accurate as you like.
43 static const double PI = 3.14159265358979323846;
45 inline bool
46 isFinite(double d)
48 #if defined(HAVE_FINITE) && !defined(HAVE_ISFINITE)
49 return (finite(d));
50 #else
51 // Put using namespace std; here if you have to
52 // put it anywhere.
53 using namespace std;
54 return (isfinite(d));
55 #endif
58 inline double
59 infinite_to_zero(double x)
61 return isFinite(x) ? x : 0.0;
64 template <typename T>
65 inline T
66 clamp(T i, T min, T max)
68 assert(min <= max);
69 return std::max<T>(min, std::min<T>(i, max));
72 template<typename T>
73 inline T
74 lerp(T a, T b, T f)
76 return (b - a) * f + a;
79 inline int
80 frnd(float f)
82 return static_cast<int>(f + 0.5f);
85 inline double
86 twipsToPixels(int i)
88 return static_cast<double>(i / 20.0);
91 template<size_t Factor>
92 boost::int32_t
93 truncateWithFactor(double a)
96 const double factor = static_cast<double>(Factor);
98 // This truncates large values without relying on undefined behaviour.
99 // For very large values of 'a' it is noticeably slower than the UB
100 // version (due to fmod), but should always be legal behaviour. For
101 // ordinary values (within ±1.07374e+08 pixels) it is comparable to
102 // the UB version for speed. Because values outside the limit are
103 // extremely rare, using this safe version has no implications for
104 // performance under normal circumstances.
105 static const double upperUnsignedLimit =
106 std::numeric_limits<boost::uint32_t>::max() + 1.0;
107 static const double upperSignedLimit =
108 std::numeric_limits<boost::int32_t>::max() / factor;
109 static const double lowerSignedLimit =
110 std::numeric_limits<boost::int32_t>::min() / factor;
112 if (a >= lowerSignedLimit && a <= upperSignedLimit) {
113 return static_cast<boost::int32_t>(a * factor);
116 // This slow truncation happens only in very unlikely cases.
117 return a >= 0 ?
118 static_cast<boost::uint32_t>(
119 std::fmod(a * factor, upperUnsignedLimit))
121 -static_cast<boost::uint32_t>(
122 std::fmod(-a * factor, upperUnsignedLimit));
125 // truncate when overflow occurs.
126 inline boost::int32_t
127 pixelsToTwips(double a)
129 return truncateWithFactor<20>(a);
132 } // namespace gnash
134 #endif