/src/freeimage-svn/FreeImage/trunk/Source/OpenEXR/Imath/ImathMath.h
Line  | Count  | Source  | 
1  |  | ///////////////////////////////////////////////////////////////////////////  | 
2  |  | //  | 
3  |  | // Copyright (c) 2002-2012, Industrial Light & Magic, a division of Lucas  | 
4  |  | // Digital Ltd. LLC  | 
5  |  | //   | 
6  |  | // All rights reserved.  | 
7  |  | //   | 
8  |  | // Redistribution and use in source and binary forms, with or without  | 
9  |  | // modification, are permitted provided that the following conditions are  | 
10  |  | // met:  | 
11  |  | // *       Redistributions of source code must retain the above copyright  | 
12  |  | // notice, this list of conditions and the following disclaimer.  | 
13  |  | // *       Redistributions in binary form must reproduce the above  | 
14  |  | // copyright notice, this list of conditions and the following disclaimer  | 
15  |  | // in the documentation and/or other materials provided with the  | 
16  |  | // distribution.  | 
17  |  | // *       Neither the name of Industrial Light & Magic nor the names of  | 
18  |  | // its contributors may be used to endorse or promote products derived  | 
19  |  | // from this software without specific prior written permission.   | 
20  |  | //   | 
21  |  | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS  | 
22  |  | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT  | 
23  |  | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR  | 
24  |  | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT  | 
25  |  | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,  | 
26  |  | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT  | 
27  |  | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,  | 
28  |  | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY  | 
29  |  | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT  | 
30  |  | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE  | 
31  |  | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  | 
32  |  | //  | 
33  |  | ///////////////////////////////////////////////////////////////////////////  | 
34  |  |  | 
35  |  |  | 
36  |  |  | 
37  |  | #ifndef INCLUDED_IMATHMATH_H  | 
38  |  | #define INCLUDED_IMATHMATH_H  | 
39  |  |  | 
40  |  | //----------------------------------------------------------------------------  | 
41  |  | //  | 
42  |  | //  ImathMath.h  | 
43  |  | //  | 
44  |  | //  This file contains template functions which call the double-  | 
45  |  | //  precision math functions defined in math.h (sin(), sqrt(),  | 
46  |  | //  exp() etc.), with specializations that call the faster  | 
47  |  | //  single-precision versions (sinf(), sqrtf(), expf() etc.)  | 
48  |  | //  when appropriate.  | 
49  |  | //  | 
50  |  | //  Example:  | 
51  |  | //  | 
52  |  | //      double x = Math<double>::sqrt (3);  // calls ::sqrt(double);  | 
53  |  | //      float  y = Math<float>::sqrt (3); // calls ::sqrtf(float);  | 
54  |  | //  | 
55  |  | //  When would I want to use this?  | 
56  |  | //  | 
57  |  | //  You may be writing a template which needs to call some function  | 
58  |  | //  defined in math.h, for example to extract a square root, but you  | 
59  |  | //  don't know whether to call the single- or the double-precision  | 
60  |  | //  version of this function (sqrt() or sqrtf()):  | 
61  |  | //  | 
62  |  | //      template <class T>  | 
63  |  | //      T  | 
64  |  | //      glorp (T x)  | 
65  |  | //      { | 
66  |  | //    return sqrt (x + 1);    // should call ::sqrtf(float)  | 
67  |  | //      }         // if x is a float, but we  | 
68  |  | //            // don't know if it is  | 
69  |  | //  | 
70  |  | //  Using the templates in this file, you can make sure that  | 
71  |  | //  the appropriate version of the math function is called:  | 
72  |  | //  | 
73  |  | //      template <class T>  | 
74  |  | //      T  | 
75  |  | //      glorp (T x, T y)  | 
76  |  | //      { | 
77  |  | //    return Math<T>::sqrt (x + 1); // calls ::sqrtf(float) if x  | 
78  |  | //      }         // is a float, ::sqrt(double)  | 
79  |  | //                // otherwise  | 
80  |  | //  | 
81  |  | //----------------------------------------------------------------------------  | 
82  |  |  | 
83  |  | #include "ImathPlatform.h"  | 
84  |  | #include "ImathLimits.h"  | 
85  |  | #include "ImathNamespace.h"  | 
86  |  | #include <math.h>  | 
87  |  |  | 
88  |  | IMATH_INTERNAL_NAMESPACE_HEADER_ENTER  | 
89  |  |  | 
90  |  |  | 
91  |  | template <class T>  | 
92  |  | struct Math  | 
93  |  | { | 
94  |  |    static T acos  (T x)   {return ::acos (double(x));}   | 
95  |  |    static T asin  (T x)   {return ::asin (double(x));} | 
96  |  |    static T atan  (T x)   {return ::atan (double(x));} | 
97  |  |    static T atan2 (T x, T y)  {return ::atan2 (double(x), double(y));} | 
98  |  |    static T cos   (T x)   {return ::cos (double(x));} | 
99  |  |    static T sin   (T x)   {return ::sin (double(x));} | 
100  |  |    static T tan   (T x)   {return ::tan (double(x));} | 
101  |  |    static T cosh  (T x)   {return ::cosh (double(x));} | 
102  |  |    static T sinh  (T x)   {return ::sinh (double(x));} | 
103  |  |    static T tanh  (T x)   {return ::tanh (double(x));} | 
104  |  |    static T exp   (T x)   {return ::exp (double(x));} | 
105  |  |    static T log   (T x)   {return ::log (double(x));} | 
106  |  |    static T log10 (T x)   {return ::log10 (double(x));} | 
107  |  |    static T modf  (T x, T *iptr)  | 
108  |  |    { | 
109  |  |         double ival;  | 
110  |  |         T rval( ::modf (double(x),&ival));  | 
111  |  |   *iptr = ival;  | 
112  |  |   return rval;  | 
113  |  |    }  | 
114  |  |    static T pow   (T x, T y)  {return ::pow (double(x), double(y));} | 
115  |  |    static T sqrt  (T x)   {return ::sqrt (double(x));} | 
116  |  |    static T ceil  (T x)   {return ::ceil (double(x));} | 
117  |  |    static T fabs  (T x)   {return ::fabs (double(x));} | 
118  |  |    static T floor (T x)   {return ::floor (double(x));} | 
119  |  |    static T fmod  (T x, T y)  {return ::fmod (double(x), double(y));} | 
120  |  |    static T hypot (T x, T y)  {return ::hypot (double(x), double(y));} | 
121  |  | };  | 
122  |  |  | 
123  |  |  | 
124  |  | template <>  | 
125  |  | struct Math<float>  | 
126  |  | { | 
127  | 0  |    static float acos  (float x)     {return ::acosf (x);}   | 
128  | 0  |    static float asin  (float x)     {return ::asinf (x);} | 
129  | 0  |    static float atan  (float x)     {return ::atanf (x);} | 
130  | 0  |    static float atan2 (float x, float y)  {return ::atan2f (x, y);} | 
131  | 0  |    static float cos   (float x)     {return ::cosf (x);} | 
132  | 0  |    static float sin   (float x)     {return ::sinf (x);} | 
133  | 0  |    static float tan   (float x)     {return ::tanf (x);} | 
134  | 0  |    static float cosh  (float x)     {return ::coshf (x);} | 
135  | 0  |    static float sinh  (float x)     {return ::sinhf (x);} | 
136  | 0  |    static float tanh  (float x)     {return ::tanhf (x);} | 
137  | 0  |    static float exp   (float x)     {return ::expf (x);} | 
138  | 0  |    static float log   (float x)     {return ::logf (x);} | 
139  | 0  |    static float log10 (float x)     {return ::log10f (x);} | 
140  | 0  |    static float modf  (float x, float *y) {return ::modff (x, y);} | 
141  | 0  |    static float pow   (float x, float y)  {return ::powf (x, y);} | 
142  | 0  |    static float sqrt  (float x)     {return ::sqrtf (x);} | 
143  | 0  |    static float ceil  (float x)     {return ::ceilf (x);} | 
144  | 0  |    static float fabs  (float x)     {return ::fabsf (x);} | 
145  | 0  |    static float floor (float x)     {return ::floorf (x);} | 
146  | 0  |    static float fmod  (float x, float y)  {return ::fmodf (x, y);} | 
147  |  | #if !defined(_MSC_VER)  | 
148  | 0  |    static float hypot (float x, float y)  {return ::hypotf (x, y);} | 
149  |  | #else  | 
150  |  |    static float hypot (float x, float y)  {return ::sqrtf(x*x + y*y);} | 
151  |  | #endif  | 
152  |  | };  | 
153  |  |  | 
154  |  |  | 
155  |  | //--------------------------------------------------------------------------  | 
156  |  | // Don Hatch's version of sin(x)/x, which is accurate for very small x.  | 
157  |  | // Returns 1 for x == 0.  | 
158  |  | //--------------------------------------------------------------------------  | 
159  |  |  | 
160  |  | template <class T>  | 
161  |  | inline T  | 
162  |  | sinx_over_x (T x)  | 
163  |  | { | 
164  |  |     if (x * x < limits<T>::epsilon())  | 
165  |  |   return T (1);  | 
166  |  |     else  | 
167  |  |   return Math<T>::sin (x) / x;  | 
168  |  | }  | 
169  |  |  | 
170  |  |  | 
171  |  | //--------------------------------------------------------------------------  | 
172  |  | // Compare two numbers and test if they are "approximately equal":  | 
173  |  | //  | 
174  |  | // equalWithAbsError (x1, x2, e)  | 
175  |  | //  | 
176  |  | //  Returns true if x1 is the same as x2 with an absolute error of  | 
177  |  | //  no more than e,  | 
178  |  | //    | 
179  |  | //  abs (x1 - x2) <= e  | 
180  |  | //  | 
181  |  | // equalWithRelError (x1, x2, e)  | 
182  |  | //  | 
183  |  | //  Returns true if x1 is the same as x2 with an relative error of  | 
184  |  | //  no more than e,  | 
185  |  | //    | 
186  |  | //  abs (x1 - x2) <= e * x1  | 
187  |  | //  | 
188  |  | //--------------------------------------------------------------------------  | 
189  |  |  | 
190  |  | template <class T>  | 
191  |  | inline bool  | 
192  |  | equalWithAbsError (T x1, T x2, T e)  | 
193  |  | { | 
194  |  |     return ((x1 > x2)? x1 - x2: x2 - x1) <= e;  | 
195  |  | }  | 
196  |  |  | 
197  |  |  | 
198  |  | template <class T>  | 
199  |  | inline bool  | 
200  |  | equalWithRelError (T x1, T x2, T e)  | 
201  |  | { | 
202  |  |     return ((x1 > x2)? x1 - x2: x2 - x1) <= e * ((x1 > 0)? x1: -x1);  | 
203  |  | }  | 
204  |  |  | 
205  |  |  | 
206  |  | IMATH_INTERNAL_NAMESPACE_HEADER_EXIT  | 
207  |  |  | 
208  |  | #endif // INCLUDED_IMATHMATH_H  |