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 javolution.context.ObjectFactory;
012import javolution.lang.MathLib;
013import javolution.text.Text;
014import javolution.text.TypeFormat;
015import javolution.xml.XMLFormat;
016import javolution.xml.stream.XMLStreamException;
017
018/**
019 * <p> This class represents a 64 bits integer number.</p>
020 * 
021 * @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
022 * @version 3.0, February 13, 2006
023 * @see <a href="http://en.wikipedia.org/wiki/Integer">
024 *      Wikipedia: Integer</a>
025 */
026public final class Integer64 extends Number<Integer64> {
027
028    /**
029     * Holds the default XML representation for 64 bits integer numbers.
030     * This representation consists of a simple <code>value</code> attribute
031     * holding the {@link #toText() textual} representation.
032     */
033    static final XMLFormat<Integer64> XML = new XMLFormat<Integer64>(Integer64.class) {
034
035        @Override
036        public Integer64 newInstance(Class<Integer64> cls, InputElement xml)
037                throws XMLStreamException {
038            return Integer64.valueOf(xml.getAttribute("value", 0L));
039        }
040
041        public void write(Integer64 integer64, OutputElement xml)
042                throws XMLStreamException {
043            xml.setAttribute("value", integer64._value);
044        }
045
046        public void read(InputElement xml, Integer64 integer64) {
047            // Nothing to do, immutable.
048        }
049    };
050 
051    /**
052     * Holds the factory used to produce 64 bits integer instances.
053     */
054    private static final ObjectFactory<Integer64> FACTORY = new ObjectFactory<Integer64>() {
055
056        protected Integer64 create() {
057            return new Integer64();
058        }
059    };
060
061    /**
062     * The 64 bits floating point representing zero.
063     */
064    public static final Integer64 ZERO = new Integer64(0L);
065
066    /**
067     * The 64 bits floating point representing one.
068     */
069    public static final Integer64 ONE = new Integer64(1L);
070
071    /**
072     * The associated long value.
073     */
074    private long _value;
075
076    /**
077     * Default constructor.
078     */
079    private Integer64() {
080    }
081
082    /**
083     * Returns the 64 bits integer from the specified <code>long</code> value.
084     *
085     * @param  longValue the <code>long</code> value for this number.
086     * @see    #longValue()
087     */
088    private Integer64(long longValue) {
089         _value = longValue;
090    }
091
092    /**
093     * Returns the 64 bits integer from the specified <code>long</code> value.
094     *
095     * @param  longValue the <code>long</code> value for this number.
096     * @return the corresponding number.
097     * @see    #longValue()
098     */
099    public static Integer64 valueOf(long longValue) {
100        Integer64 r = FACTORY.object();
101        r._value = longValue;
102        return r;
103    }
104
105    /**
106     * Returns the number for the specified character sequence.
107     *
108     * @param  chars the character sequence.
109     * @return the corresponding number.
110     */
111    public static Integer64 valueOf(CharSequence chars) {
112        Integer64 r = FACTORY.object();
113        r._value = TypeFormat.parseLong(chars);
114        return r;
115    }
116
117    /**
118     * Returns the opposite of this number.
119     *
120     * @return <code>-this</code>.
121     */
122    public Integer64 opposite() {
123        Integer64 r = FACTORY.object();
124        r._value = -this._value;
125        return r;
126    }
127
128    /**
129     * Returns the sum of this number with the one specified.
130     *
131     * @param  that the number to be added.
132     * @return <code>this + that</code>.
133     */
134    public Integer64 plus(Integer64 that) {
135        Integer64 r = FACTORY.object();
136        r._value = this._value + that._value;
137        return r;
138    }
139
140    /**
141     * Returns the sum of this number with the specifice value.
142     *
143     * @param  value the value to be added.
144     * @return <code>this + value</code>.
145     */
146    public Integer64 plus(long value) {
147        Integer64 r = FACTORY.object();
148        r._value = this._value + value;
149        return r;
150    }
151
152    /**
153     * Returns the difference between this number and the one specified.
154     *
155     * @param  that the number to be subtracted.
156     * @return <code>this - that</code>.
157     */
158    public Integer64 minus(Integer64 that) {
159        Integer64 r = FACTORY.object();
160        r._value = this._value - that._value;
161        return r;
162    }
163
164    /**
165     * Returns the difference between this number and the specified value
166     *
167     * @param  value the value to be subtracted.
168     * @return <code>this - value</code>.
169     */
170    public Integer64 minus(long value) {
171        Integer64 r = FACTORY.object();
172        r._value = this._value - value;
173        return r;
174    }
175
176    /**
177     * Returns the product of this number with the one specified.
178     *
179     * @param  that the number multiplier.
180     * @return <code>this · that</code>.
181     */
182    public Integer64 times(Integer64 that) {
183        Integer64 r = FACTORY.object();
184        r._value = this._value * that._value;
185        return r;
186    }
187
188    /**
189     * Returns the product of this number with the specified value.
190     *
191     * @param  value the value multiplier.
192     * @return <code>this · value</code>.
193     */
194    public Integer64 times(long value) {
195        Integer64 r = FACTORY.object();
196        r._value = this._value * value;
197        return r;
198    }
199
200    /**
201     * Returns this number divided by the one specified.
202     *
203     * @param  that the number divisor.
204     * @return <code>this / that</code>.
205     */
206    public Integer64 divide(Integer64 that) {
207        Integer64 r = FACTORY.object();
208        r._value = this._value / that._value;
209        return r;
210    }
211
212    /**
213     * Returns this number divided by the specified value.
214     *
215     * @param  value the value divisor.
216     * @return <code>this / value</code>.
217     */
218    public Integer64 divide(long value) {
219        Integer64 r = FACTORY.object();
220        r._value = this._value / value;
221        return r;
222    }
223
224    /**
225     * Compares the magnitude of this number with that number.
226     *
227     * @return <code>|this| > |that|</code>
228     */
229    public boolean isLargerThan(Integer64 that) {
230        return MathLib.abs(this._value) > MathLib.abs(that._value);
231    }
232
233    /**
234     * Returns the absolute value of this number.
235     *
236     * @return <code>|this|</code>.
237     */
238    public Integer64 abs() {
239        Integer64 r = FACTORY.object();
240        r._value = MathLib.abs(this._value);
241        return r;
242    }
243
244    /**
245     * Returns the decimal text representation of this number.
246     *
247     * @return the text representation of this number.
248     */
249    public Text toText() {
250        return Text.valueOf(_value);
251    }
252
253    /**
254     * Compares this number against the specified object.
255     *
256     * @param  that the object to compare with.
257     * @return <code>true</code> if the objects are the same;
258     *         <code>false</code> otherwise.
259     */
260    public boolean equals(Object that) {
261        return (that instanceof Integer64)
262                && (this._value == ((Integer64) that)._value);
263    }
264
265    /**
266     * Compares this number against the specified value.
267     *
268     * @param  value the value to compare with.
269     * @return <code>this.longValue() == value</code>
270     */
271    public boolean equals(long value) {
272        return this._value == value;
273    }
274
275    /**
276     * Compares this number with the specified value for order.
277     * 
278     * @param value the value to be compared with.
279     * @return a negative integer, zero, or a positive integer as this number
280     *        is less than, equal to, or greater than the specified value.
281     */
282    public int compareTo(long value) {
283        if (this._value < value) {
284            return -1;
285        } else if (this._value > value) {
286            return 1;
287        } else {
288            return 0;
289        }
290    }
291    
292    /**
293     * Returns the hash code for this number.
294     * 
295     * @return the hash code value.
296     */
297    public int hashCode() {
298        int h = Float.floatToIntBits((float) _value);
299        h += ~(h << 9);
300        h ^= (h >>> 14);
301        h += (h << 4);
302        return h ^ (h >>> 10);
303    }
304
305    @Override
306    public long longValue() {
307        return _value;
308    }
309
310    @Override
311    public double doubleValue() {
312        return _value;
313    }
314
315    @Override
316    public int compareTo(Integer64 that) {
317        return compareTo(that._value);
318    }
319
320    @Override
321    public Integer64 copy() {
322        return Integer64.valueOf(_value);
323    }
324
325    private static final long serialVersionUID = 1L;
326}