001    //$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/tags/2.1/src/org/deegree/model/csct/resources/XMath.java $
002    /*----------------    FILE HEADER  ------------------------------------------
003    
004     This file is part of deegree.
005     Copyright (C) 2001 by:
006     EXSE, Department of Geography, University of Bonn
007     http://www.giub.uni-bonn.de/exse/
008     lat/lon GmbH
009     http://www.lat-lon.de
010    
011     It has been implemented within SEAGIS - An OpenSource implementation of OpenGIS specification
012     (C) 2001, Institut de Recherche pour le D�veloppement (http://sourceforge.net/projects/seagis/)
013     SEAGIS Contacts:  Surveillance de l'Environnement Assist�e par Satellite
014     Institut de Recherche pour le D�veloppement / US-Espace
015     mailto:seasnet@teledetection.fr
016    
017    
018     This library is free software; you can redistribute it and/or
019     modify it under the terms of the GNU Lesser General Public
020     License as published by the Free Software Foundation; either
021     version 2.1 of the License, or (at your option) any later version.
022    
023     This library is distributed in the hope that it will be useful,
024     but WITHOUT ANY WARRANTY; without even the implied warranty of
025     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
026     Lesser General Public License for more details.
027    
028     You should have received a copy of the GNU Lesser General Public
029     License along with this library; if not, write to the Free Software
030     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
031    
032     Contact:
033    
034     Andreas Poth
035     lat/lon GmbH
036     Aennchenstr. 19
037     53115 Bonn
038     Germany
039     E-Mail: poth@lat-lon.de
040    
041     Klaus Greve
042     Department of Geography
043     University of Bonn
044     Meckenheimer Allee 166
045     53115 Bonn
046     Germany
047     E-Mail: klaus.greve@uni-bonn.de
048    
049     
050     ---------------------------------------------------------------------------*/
051    package org.deegree.model.csct.resources;
052    
053    // Miscellaneous
054    
055    /**
056     * Simple mathematical functions. Some of those function will
057     * be removed if JavaSoft provide a standard implementation
058     * or fix some issues in Bug Parade:<br>
059     * <ul>
060     *   <li><a href="http://developer.java.sun.com/developer/bugParade/bugs/4074599.html">Implement log10 (base 10 logarithm)</a></li>
061     *   <li><a href="http://developer.java.sun.com/developer/bugParade/bugs/4358794.html">implement pow10 (power of 10) with optimization for integer powers</a>/li>
062     *   <li><a href="http://developer.java.sun.com/developer/bugParade/bugs/4461243.html">Math.acos is very slow</a></li>
063     * </ul>
064     *
065     * @version 1.0
066     * @author Martin Desruisseaux
067     */
068    public final class XMath {
069        /**
070         * Natural logarithm of 10.
071         * Approximatively equals to 2.302585.
072         */
073        public static final double LN10 = 2.3025850929940456840179914546844;
074    
075        /**
076         * Table of some integer powers of 10. Used
077         * for fast computation of {@link #pow10(int)}.
078         */
079        private static final double[] POW10 = { 1E+00, 1E+01, 1E+02, 1E+03, 1E+04, 1E+05, 1E+06, 1E+07,
080                                               1E+08, 1E+09, 1E+10, 1E+11, 1E+12, 1E+13, 1E+14, 1E+15,
081                                               1E+16, 1E+17, 1E+18, 1E+19, 1E+20, 1E+21, 1E+22, 1E+23 };
082    
083        /**
084         * Do not allow instantiation of this class.
085         */
086        private XMath() {
087        }
088    
089        /**
090         * Compute the hypothenuse (<code>sqrt(x�+y�)</code>).
091         */
092        public static double hypot( double x, double y ) {
093            return Math.sqrt( x * x + y * y );
094        }
095    
096        /**
097         * Compute the logarithm in base 10. See
098         * http://developer.java.sun.com/developer/bugParade/bugs/4074599.html.
099         */
100        public static double log10( double x ) {
101            return Math.log( x ) / LN10;
102        }
103    
104        /**
105         * Compute 10 power <var>x</var>.
106         */
107        public static double pow10( double x ) {
108            final int ix = (int) x;
109            if ( ix == x ) {
110                return pow10( ix );
111            }
112            return Math.pow( 10.0, x );
113        }
114    
115        /**
116         * Compute 10 power <var>x</var>. This computation is very fast
117         * for small power of 10 and avoir some rounding error issue (see
118         * http://developer.java.sun.com/developer/bugParade/bugs/4358794.html).
119         */
120        public static double pow10( final int x ) {
121            if ( x >= 0 ) {
122                if ( x < POW10.length )
123                    return POW10[x];
124            } else if ( x != Integer.MIN_VALUE ) {
125                final int nx = -x;
126                if ( nx < POW10.length )
127                    return 1 / POW10[nx];
128            }
129            try {
130                /*
131                 * Note: Method 'Math.pow(10,x)' has rounding errors: it doesn't always returns the
132                 *       closest IEEE floating point representation. Method 'Double.parseDouble("1E"+x)'
133                 *       gives as good or better numbers for ALL integer powers, but is much slower.
134                 *       The difference is usually negligible, but powers of 10 is a special case
135                 *       since it is often used for scaling axis or formatting human-readable output.
136                 *       We hope that the current workaround is only temporary.
137                 *       (see http://developer.java.sun.com/developer/bugParade/bugs/4358794.html).
138                 */
139                return Double.parseDouble( "1E" + x );
140            } catch ( NumberFormatException exception ) {
141                return StrictMath.pow( 10, x );
142            }
143        }
144    
145        /**
146         * Returns the sign of <var>x</var>. This method returns
147         *    -1 if <var>x</var> is negative,
148         *     0 if <var>x</var> is null or <code>NaN</code> and
149         *    +1 if <var>x</var> is positive.
150         */
151        public static int sgn( double x ) {
152            if ( x > 0 ) {
153                return +1;
154            }
155            if ( x < 0 ) {
156                return -1;
157            }
158            return 0;
159        }
160    
161        /**
162         * Returns the sign of <var>x</var>. This method returns
163         *    -1 if <var>x</var> is negative,
164         *     0 if <var>x</var> is null or <code>NaN</code> and
165         *    +1 if <var>x</var> is positive.
166         */
167        public static int sgn( float x ) {
168            if ( x > 0 ) {
169                return +1;
170            }
171            if ( x < 0 ) {
172                return -1;
173            }
174            return 0;
175        }
176    
177        /**
178         * Returns the sign of <var>x</var>. This method returns
179         *    -1 if <var>x</var> is negative,
180         *     0 if <var>x</var> is null and
181         *    +1 if <var>x</var> is positive.
182         */
183        public static int sgn( long x ) {
184            if ( x > 0 ) {
185                return +1;
186            }
187            if ( x < 0 ) {
188                return -1;
189            }
190            return 0;
191        }
192    
193        /**
194         * Returns the sign of <var>x</var>. This method returns
195         *    -1 if <var>x</var> is negative,
196         *     0 if <var>x</var> is null and
197         *    +1 if <var>x</var> is positive.
198         */
199        public static int sgn( int x ) {
200            if ( x > 0 ) {
201                return +1;
202            }
203            if ( x < 0 ) {
204                return -1;
205            }
206            return 0;
207        }
208    
209        /**
210         * Returns the sign of <var>x</var>. This method returns
211         *    -1 if <var>x</var> is negative,
212         *     0 if <var>x</var> is null and
213         *    +1 if <var>x</var> is positive.
214         */
215        public static short sgn( short x ) {
216            if ( x > 0 ) {
217                return (short) +1;
218            }
219            if ( x < 0 ) {
220                return (short) -1;
221            }
222            return (short) 0;
223        }
224    
225        /**
226         * Returns the sign of <var>x</var>. This method returns
227         *    -1 if <var>x</var> is negative,
228         *     0 if <var>x</var> is null and
229         *    +1 if <var>x</var> is positive.
230         */
231        public static byte sgn( byte x ) {
232            if ( x > 0 ) {
233                return (byte) +1;
234            }
235            if ( x < 0 ) {
236                return (byte) -1;
237            }
238            return (byte) 0;
239        }
240    }