001/*
002 * JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
003 * Copyright (C) 2006 - JScience (http://jscience.org/)
004 * All rights reserved.
005 * 
006 * Permission to use, copy, modify, and distribute this software is
007 * freely granted, provided that this notice is preserved.
008 */
009package org.jscience.mathematics.number;
010
011import org.jscience.mathematics.structure.Field;
012
013import javolution.context.ObjectFactory;
014import javolution.lang.MathLib;
015import javolution.text.Text;
016import javolution.text.TypeFormat;
017import javolution.xml.XMLFormat;
018import javolution.xml.stream.XMLStreamException;
019
020/**
021 * <p> This class represents a 64 bits floating point number.</p>
022 * 
023 * @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
024 * @version 3.0, February 13, 2006
025 */
026public final class Float64 extends Number<Float64> implements Field<Float64> {
027
028    /**
029     * Holds the default XML representation for 64 bits floating point numbers.
030     * This representation consists of a simple <code>value</code> attribute
031     * holding the {@link #toText() textual} representation.
032     */
033    static final XMLFormat<Float64> XML = new XMLFormat<Float64>(Float64.class) {
034
035        @Override
036        public Float64 newInstance(Class<Float64> cls, InputElement xml)
037                throws XMLStreamException {
038            return Float64.valueOf(xml.getAttribute("value", 0.0));
039        }
040
041        public void write(Float64 float64, OutputElement xml)
042                throws XMLStreamException {
043            xml.setAttribute("value", float64._value);
044        }
045
046        public void read(InputElement xml, Float64 float64) {
047            // Nothing to do, immutable.
048        }
049    };
050
051    /**
052     * Holds the factory used to produce 64 bits float instances.
053     */
054    private static final ObjectFactory<Float64> FACTORY = new ObjectFactory<Float64>() {
055
056        protected Float64 create() {
057            return new Float64();
058        }
059    };
060
061    /**
062     * The 64 bits floating point representing zero.
063     */
064    public static final Float64 ZERO = new Float64(0.0);
065
066    /**
067     * The 64 bits floating point representing one.
068     */
069    public static final Float64 ONE = new Float64(1.0);
070
071    /**
072     * The associated double value.
073     */
074    private double _value;
075
076    /**
077     * Default constructor.
078     */
079    private Float64() {
080    }
081
082    /**
083     * Creates a 64 bits float having the specified <code>double</code> value.
084     *
085     * @param  doubleValue the <code>double</code> value for this number.
086     */
087    private Float64(double doubleValue) {
088        _value = doubleValue;
089    }
090
091    /**
092     * Returns the 64 bits float from the specified <code>double</code> value.
093     *
094     * @param  doubleValue the <code>double</code> value for this number.
095     * @return the corresponding number.
096     * @see    #doubleValue()
097     */
098    public static Float64 valueOf(double doubleValue) {
099        Float64 r = FACTORY.object();
100        r._value = doubleValue;
101        return r;
102    }
103
104    /**
105     * Returns the number for the specified character sequence.
106     *
107     * @param  chars the character sequence.
108     * @return the corresponding number.
109     */
110    public static Float64 valueOf(CharSequence chars) {
111        Float64 r = FACTORY.object();
112        r._value = TypeFormat.parseDouble(chars);
113        return r;
114    }
115
116    /**
117     * Indicates if this number is infinite.
118     *
119     * @return <code>true</code> if this number is infinite;
120     *         <code>false</code> otherwise.
121     */
122    public boolean isInfinite() {
123        return Double.isInfinite(_value);
124    }
125
126    /**
127     * Indicates if this number is not a number.
128     *
129     * @return <code>true</code> if this number is NaN;
130     *         <code>false</code> otherwise.
131     */
132    public boolean isNaN() {
133        return Double.isNaN(_value);
134    }
135
136    /**
137     * Returns the closest integer value to this 64 bits floating point number.
138     * 
139     * @return this number rounded to the nearest integer.
140     */
141    public long round() {
142        return MathLib.round(_value);
143    }
144
145    /**
146     * Returns the opposite of this number.
147     *
148     * @return <code>-this</code>.
149     */
150    public Float64 opposite() {
151        Float64 r = FACTORY.object();
152        r._value = -this._value;
153        return r;
154    }
155
156    /**
157     * Returns the sum of this number with the one specified.
158     *
159     * @param  that the number to be added.
160     * @return <code>this + that</code>.
161     */
162    public Float64 plus(Float64 that) {
163        Float64 r = FACTORY.object();
164        r._value = this._value + that._value;
165        return r;
166    }
167
168    /**
169     * Returns the sum of this number with the specified value.
170     *
171     * @param  value the value to be added.
172     * @return <code>this + value</code>.
173     */
174    public Float64 plus(double value) {
175        Float64 r = FACTORY.object();
176        r._value = this._value + value;
177        return r;
178    }
179
180    /**
181     * Returns the difference between this number and the one specified.
182     *
183     * @param  that the number to be subtracted.
184     * @return <code>this - that</code>.
185     */
186    public Float64 minus(Float64 that) {
187        Float64 r = FACTORY.object();
188        r._value = this._value - that._value;
189        return r;
190    }
191
192    /**
193     * Returns the difference between this number and the specified value.
194     *
195     * @param  value the value to be subtracted.
196     * @return <code>this - value</code>.
197     */
198    public Float64 minus(double value) {
199        Float64 r = FACTORY.object();
200        r._value = this._value - value;
201        return r;
202    }
203
204    /**
205     * Returns the product of this number with the one specified.
206     *
207     * @param  that the number multiplier.
208     * @return <code>this · that</code>.
209     */
210    public Float64 times(Float64 that) {
211        Float64 r = FACTORY.object();
212        r._value = this._value * that._value;
213        return r;
214    }
215
216    /**
217     * Returns the product of this number with the specified value.
218     *
219     * @param  value the value multiplier.
220     * @return <code>this · value</code>.
221     */
222    public Float64 times(double value) {
223        Float64 r = FACTORY.object();
224        r._value = this._value * value;
225        return r;
226    }
227
228    /**
229     * Returns the reciprocal of this number.
230     *
231     * @return <code>1 / this</code>.
232     */
233    public Float64 inverse() {
234        Float64 r = FACTORY.object();
235        r._value = 1.0 / this._value;
236        return r;
237    }
238
239    /**
240     * Returns this number divided by the one specified.
241     *
242     * @param  that the number divisor.
243     * @return <code>this / that</code>.
244     */
245    public Float64 divide(Float64 that) {
246        Float64 r = FACTORY.object();
247        r._value = this._value / that._value;
248        return r;
249    }
250
251    /**
252     * Returns this number divided by the specified value.
253     *
254     * @param  value the value divisor.
255     * @return <code>this / value</code>.
256     */
257    public Float64 divide(double value) {
258        Float64 r = FACTORY.object();
259        r._value = this._value / value;
260        return r;
261    }
262
263    /**
264     * Compares the absolute value of this number with that number.
265     * 
266     * @param that the number to compare with.
267     * @return <code>|this| > |that|</code>
268     */
269    public boolean isLargerThan(Float64 that) {
270        return MathLib.abs(this._value) > MathLib.abs(that._value);
271    }
272 
273    /**
274     * Returns the absolute value of this number.
275     *
276     * @return <code>|this|</code>.
277     */
278    public Float64 abs() {
279        Float64 r = FACTORY.object();
280        r._value = MathLib.abs(this._value);
281        return r;
282    }
283
284    /**
285     * Returns the positive square root of this number.
286     *
287     * @return <code>sqrt(this)</code>.
288     */
289    public Float64 sqrt() {
290        Float64 r = FACTORY.object();
291        r._value = MathLib.sqrt(this._value);
292        return r;
293    }
294
295    /**
296     * Returns the exponential number <i>e</i> raised to the power of this
297     * number.
298     *
299     * @return <code>exp(this)</code>.
300     */
301    public Float64 exp() {
302        Float64 r = FACTORY.object();
303        r._value = MathLib.exp(this._value);
304        return r;
305    }
306
307    /**
308     * Returns the natural logarithm (base e) of this number.
309     *
310     * @return <code>log(this)</code>.
311     */
312    public Float64 log() {
313        Float64 r = FACTORY.object();
314        r._value = MathLib.log(this._value);
315        return r;
316    }
317
318    /**
319     * Returns this number raised to the power of the specified exponent.
320     *
321     * @param  that the exponent.
322     * @return <code>this**that</code>.
323     */
324    public Float64 pow(Float64 that) {
325        Float64 r = FACTORY.object();
326        r._value = MathLib.pow(this._value, that._value);
327        return r;
328    }
329
330    /**
331     * Returns this number raised to the specified power.
332     *
333     * @param  e the exponent.
334     * @return <code>this**e</code>.
335     */
336    public Float64 pow(double e) {
337        Float64 r = FACTORY.object();
338        r._value = MathLib.pow(this._value, e);
339        return r;
340    }
341
342    /**
343     * Returns the decimal text representation of this number.
344     *
345     * @return the text representation of this number.
346     */
347    public Text toText() {
348        return Text.valueOf(_value);
349    }
350
351    /**
352     * Compares this number against the specified object.
353     *
354     * @param  that the object to compare with.
355     * @return <code>true</code> if the objects are the same;
356     *         <code>false</code> otherwise.
357     */
358    public boolean equals(Object that) {
359        return (that instanceof Float64)
360                && (this._value == ((Float64) that)._value);
361    }
362
363    /**
364     * Indicates if this number is equal to the specified value.
365     * 
366     * @param value the value to compare with.
367     * @return <code>this.doubleValue() == value</code>.
368     */
369    public boolean equals(double value) {
370        return this._value == value;
371    }
372
373    /**
374     * Compares this number with the specified value for order.
375     * 
376     * @param value the value to be compared with.
377     * @return a negative integer, zero, or a positive integer as this number
378     *        is less than, equal to, or greater than the specified value.
379     */
380    public int compareTo(double value) {
381        if (this._value < value) {
382            return -1;
383        } else if (this._value > value) {
384            return 1;
385        } else {
386            long l1 = Double.doubleToLongBits(this._value);
387            long l2 = Double.doubleToLongBits(value);
388            return (l1 == l2 ? 0 : (l1 < l2 ? -1 : 1));
389        }
390    }
391
392    /**
393     * Returns the hash code for this number.
394     * 
395     * @return the hash code value.
396     */
397    public int hashCode() {
398        int h = Float.floatToIntBits((float) _value);
399        h += ~(h << 9);
400        h ^= (h >>> 14);
401        h += (h << 4);
402        return h ^ (h >>> 10);
403    }
404
405    @Override
406    public long longValue() {
407        return (long) _value;
408    }
409
410    @Override
411    public double doubleValue() {
412        return _value;
413    }
414
415    @Override
416    public int compareTo(Float64 that) {
417        return compareTo(that._value);
418    }
419
420    @Override
421    public Float64 copy() {
422        return Float64.valueOf(_value);
423    }
424    
425    private static final long serialVersionUID = 1L;
426
427}