1 // GnashNumeric.h: vaguely useful mathematical functions.
3 // Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Free Software
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.
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.
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
25 # include "gnashconfig.h"
29 # include <ieeefp.h> // for finite()
35 #include <boost/cstdint.hpp>
37 #include <boost/utility/enable_if.hpp>
41 // Using a possible built-in pi constant M_PI, which is not in
42 // the C++ standard, has no greate advantage, so we will use this
43 // one. Make it as accurate as you like.
44 static const double PI
= 3.14159265358979323846;
49 #if defined(HAVE_FINITE) && !defined(HAVE_ISFINITE)
52 // Put using namespace std; here if you have to
60 infinite_to_zero(double x
)
62 return isFinite(x
) ? x
: 0.0;
67 clamp(T i
, T min
, T max
)
70 return std::max
<T
>(min
, std::min
<T
>(i
, max
));
77 return (b
- a
) * f
+ a
;
83 return static_cast<int>(f
+ 0.5f
);
89 return static_cast<double>(i
/ 20.0);
92 template<size_t Factor
>
94 truncateWithFactor(double a
)
97 const double factor
= static_cast<double>(Factor
);
99 // This truncates large values without relying on undefined behaviour.
100 // For very large values of 'a' it is noticeably slower than the UB
101 // version (due to fmod), but should always be legal behaviour. For
102 // ordinary values (within ±1.07374e+08 pixels) it is comparable to
103 // the UB version for speed. Because values outside the limit are
104 // extremely rare, using this safe version has no implications for
105 // performance under normal circumstances.
106 static const double upperUnsignedLimit
=
107 std::numeric_limits
<boost::uint32_t>::max() + 1.0;
108 static const double upperSignedLimit
=
109 std::numeric_limits
<boost::int32_t>::max() / factor
;
110 static const double lowerSignedLimit
=
111 std::numeric_limits
<boost::int32_t>::min() / factor
;
113 if (a
>= lowerSignedLimit
&& a
<= upperSignedLimit
) {
117 // This slow truncation happens only in very unlikely cases.
119 static_cast<boost::uint32_t>(
120 std::fmod(a
* factor
, upperUnsignedLimit
))
122 -static_cast<boost::uint32_t>(
123 std::fmod(-a
* factor
, upperUnsignedLimit
));
126 // truncate when overflow occurs.
127 inline boost::int32_t
128 pixelsToTwips(double a
)
130 return truncateWithFactor
<20>(a
);