source: NonGTP/OpenEXR/include/Imath/ImathMath.h @ 855

Revision 855, 8.7 KB checked in by igarcia, 18 years ago (diff)
Line 
1///////////////////////////////////////////////////////////////////////////
2//
3// Copyright (c) 2002, 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 <math.h>
85
86//
87// The following pragmas instruct Silicon Graphics' MipsPro C++
88// to generate inline code rather than function calls for sqrt()
89// and sqrtf().
90//
91
92#if defined(PLATFORM_IRIX) || defined(PLATFORM_IRIX64)
93
94#pragma intrinsic (::sqrt)
95#pragma intrinsic (::sqrtf)
96
97#endif
98
99namespace Imath {
100
101
102template <class T>
103struct Math
104{
105   static T     acos  (T x)             {return ::acos (double(x));}   
106   static T     asin  (T x)             {return ::asin (double(x));}
107   static T     atan  (T x)             {return ::atan (double(x));}
108   static T     atan2 (T x, T y)        {return ::atan2 (double(x), double(y));}
109   static T     cos   (T x)             {return ::cos (double(x));}
110   static T     sin   (T x)             {return ::sin (double(x));}
111   static T     tan   (T x)             {return ::tan (double(x));}
112   static T     cosh  (T x)             {return ::cosh (double(x));}
113   static T     sinh  (T x)             {return ::sinh (double(x));}
114   static T     tanh  (T x)             {return ::tanh (double(x));}
115   static T     exp   (T x)             {return ::exp (double(x));}
116   static T     log   (T x)             {return ::log (double(x));}
117   static T     log10 (T x)             {return ::log10 (double(x));}
118#if defined(PLATFORM_SUNOS5) // SUN does not seem to have floating point funcs !!
119//   static T   modf  (T x, T *y)       {return ::modf (double(x), double(y));}
120#else
121   static T     modf  (T x, T *iptr)
122   {
123        double ival;
124        T rval( ::modf (double(x),&ival));
125        *iptr = ival;
126        return rval;
127   }
128#endif
129   static T     pow   (T x, T y)        {return ::pow (double(x), double(y));}
130   static T     sqrt  (T x)             {return ::sqrt (double(x));}
131   static T     ceil  (T x)             {return ::ceil (double(x));}
132   static T     fabs  (T x)             {return ::fabs (double(x));}
133   static T     floor (T x)             {return ::floor (double(x));}
134#if defined(PLATFORM_SUNOS5) // SUN does not seem to have floating point funcs !!
135//   static T   fmod  (T x, T y)        {return ::fmod (double(x), double(y));}
136#else
137   static T     fmod  (T x, T y)        {return ::fmod (double(x), double(y));}
138#endif
139#if !defined(PLATFORM_OSF1)
140   static T     hypot (T x, T y)        {return ::hypot (double(x), double(y));}
141#endif
142};
143
144
145// Sun, Apple, and Microsoft don't have floating point funcs
146#if defined ( PLATFORM_SUNOS5 ) || defined ( PLATFORM_DARWIN_PPC )
147
148template <>
149struct Math<float>
150{
151   static float acos  (float x)                 {return ::acos (x);}   
152   static float asin  (float x)                 {return ::asin (x);}
153   static float atan  (float x)                 {return ::atan (x);}
154   static float atan2 (float x, float y)        {return ::atan2 (x, y);}
155   static float cos   (float x)                 {return ::cos (x);}
156   static float sin   (float x)                 {return ::sin (x);}
157   static float tan   (float x)                 {return ::tan (x);}
158   static float cosh  (float x)                 {return ::cosh (x);}
159   static float sinh  (float x)                 {return ::sinh (x);}
160   static float tanh  (float x)                 {return ::tanh (x);}
161   static float exp   (float x)                 {return ::exp (x);}
162   static float log   (float x)                 {return ::log (x);}
163   static float log10 (float x)                 {return ::log10 (x);}
164//   static float       modf  (float x, float *y)       {return ::modf (x, y);}
165   static float pow   (float x, float y)        {return ::pow (x, y);}
166   static float sqrt  (float x)                 {return ::sqrt (x);}
167   static float ceil  (float x)                 {return ::ceil (x);}
168   static float fabs  (float x)                 {return ::fabs (x);}
169   static float floor (float x)                 {return ::floor (x);}
170//   static float       fmod  (float x, float y)        {return ::fmod (x, y);}
171   static float hypot (float x, float y)        {return ::hypot (x, y);}
172};
173#else
174template <>
175struct Math<float>
176{
177   static float acos  (float x)                 {return ::acosf (x);}   
178   static float asin  (float x)                 {return ::asinf (x);}
179   static float atan  (float x)                 {return ::atanf (x);}
180   static float atan2 (float x, float y)        {return ::atan2f (x, y);}
181   static float cos   (float x)                 {return ::cosf (x);}
182   static float sin   (float x)                 {return ::sinf (x);}
183   static float tan   (float x)                 {return ::tanf (x);}
184   static float cosh  (float x)                 {return ::coshf (x);}
185   static float sinh  (float x)                 {return ::sinhf (x);}
186   static float tanh  (float x)                 {return ::tanhf (x);}
187   static float exp   (float x)                 {return ::expf (x);}
188   static float log   (float x)                 {return ::logf (x);}
189   static float log10 (float x)                 {return ::log10f (x);}
190   static float modf  (float x, float *y)       {return ::modff (x, y);}
191   static float pow   (float x, float y)        {return ::powf (x, y);}
192   static float sqrt  (float x)                 {return ::sqrtf (x);}
193   static float ceil  (float x)                 {return ::ceilf (x);}
194   static float fabs  (float x)                 {return ::fabsf (x);}
195   static float floor (float x)                 {return ::floorf (x);}
196   static float fmod  (float x, float y)        {return ::fmodf (x, y);}
197#if !defined(PLATFORM_OSF1) && !defined(_MSC_VER)
198   static float hypot (float x, float y)        {return ::hypotf (x, y);}
199#else
200   static float hypot (float x, float y)        {return ::sqrtf(x*x + y*y);}
201#endif
202};
203#endif
204
205
206//--------------------------------------------------------------------------
207// Compare two numbers and test if they are "approximately equal":
208//
209// equalWithAbsError (x1, x2, e)
210//
211//      Returns true if x1 is the same as x2 with an absolute error of
212//      no more than e,
213//     
214//      abs (x1 - x2) <= e
215//
216// equalWithRelError (x1, x2, e)
217//
218//      Returns true if x1 is the same as x2 with an relative error of
219//      no more than e,
220//     
221//      abs (x1 - x2) <= e * x1
222//
223//--------------------------------------------------------------------------
224
225template <class T>
226inline bool
227equalWithAbsError (T x1, T x2, T e)
228{
229    return ((x1 > x2)? x1 - x2: x2 - x1) <= e;
230}
231
232
233template <class T>
234inline bool
235equalWithRelError (T x1, T x2, T e)
236{
237    return ((x1 > x2)? x1 - x2: x2 - x1) <= e * ((x1 > 0)? x1: -x1);
238}
239
240
241
242} // namespace Imath
243
244#endif
Note: See TracBrowser for help on using the repository browser.