001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     * 
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     * 
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.commons.lang.mutable;
018    
019    import org.apache.commons.lang.math.NumberUtils;
020    
021    /**
022     * A mutable <code>double</code> wrapper.
023     * 
024     * @see Double
025     * @since 2.1
026     * @version $Id: MutableDouble.java 618693 2008-02-05 16:33:29Z sebb $
027     */
028    public class MutableDouble extends Number implements Comparable, Mutable {
029    
030        /**
031         * Required for serialization support.
032         * 
033         * @see java.io.Serializable
034         */
035        private static final long serialVersionUID = 1587163916L;
036    
037        /** The mutable value. */
038        private double value;
039    
040        /**
041         * Constructs a new MutableDouble with the default value of zero.
042         */
043        public MutableDouble() {
044            super();
045        }
046    
047        /**
048         * Constructs a new MutableDouble with the specified value.
049         * 
050         * @param value
051         *            a value.
052         */
053        public MutableDouble(double value) {
054            super();
055            this.value = value;
056        }
057    
058        /**
059         * Constructs a new MutableDouble with the specified value.
060         * 
061         * @param value
062         *            a value.
063         * @throws NullPointerException
064         *             if the object is null
065         */
066        public MutableDouble(Number value) {
067            super();
068            this.value = value.doubleValue();
069        }
070    
071        //-----------------------------------------------------------------------
072        /**
073         * Gets the value as a Double instance.
074         * 
075         * @return the value as a Double
076         */
077        public Object getValue() {
078            return new Double(this.value);
079        }
080    
081        /**
082         * Sets the value.
083         * 
084         * @param value
085         *            the value to set
086         */
087        public void setValue(double value) {
088            this.value = value;
089        }
090    
091        /**
092         * Sets the value from any Number instance.
093         * 
094         * @param value
095         *            the value to set
096         * @throws NullPointerException
097         *             if the object is null
098         * @throws ClassCastException
099         *             if the type is not a {@link Number}
100         */
101        public void setValue(Object value) {
102            setValue(((Number) value).doubleValue());
103        }
104    
105        //-----------------------------------------------------------------------
106        // shortValue and bytValue rely on Number implementation
107        /**
108         * Returns the value of this MutableDouble as a int.
109         *
110         * @return the numeric value represented by this object after conversion to type int.
111         */
112        public int intValue() {
113            return (int) value;
114        }
115    
116        /**
117         * Returns the value of this MutableDouble as a long.
118         *
119         * @return the numeric value represented by this object after conversion to type long.
120         */
121        public long longValue() {
122            return (long) value;
123        }
124    
125        /**
126         * Returns the value of this MutableDouble as a float.
127         *
128         * @return the numeric value represented by this object after conversion to type float.
129         */
130        public float floatValue() {
131            return (float) value;
132        }
133    
134        /**
135         * Returns the value of this MutableDouble as a double.
136         *
137         * @return the numeric value represented by this object after conversion to type double.
138         */
139        public double doubleValue() {
140            return value;
141        }
142    
143        /**
144         * Checks whether the double value is the special NaN value.
145         * 
146         * @return true if NaN
147         */
148        public boolean isNaN() {
149            return Double.isNaN(value);
150        }
151    
152        /**
153         * Checks whether the double value is infinite.
154         * 
155         * @return true if infinite
156         */
157        public boolean isInfinite() {
158            return Double.isInfinite(value);
159        }
160    
161        //-----------------------------------------------------------------------
162        /**
163         * Gets this mutable as an instance of Double.
164         *
165         * @return a Double instance containing the value from this mutable
166         */
167        public Double toDouble() {
168            return new Double(doubleValue());
169        }
170    
171        //-----------------------------------------------------------------------
172        /**
173         * Increments the value.
174         *
175         * @since Commons Lang 2.2
176         */
177        public void increment() {
178            value++;
179        }
180    
181        /**
182         * Decrements the value.
183         *
184         * @since Commons Lang 2.2
185         */
186        public void decrement() {
187            value--;
188        }
189    
190        //-----------------------------------------------------------------------
191        /**
192         * Adds a value.
193         * 
194         * @param operand
195         *            the value to add
196         *
197         * @since Commons Lang 2.2
198         */
199        public void add(double operand) {
200            this.value += operand;
201        }
202    
203        /**
204         * Adds a value.
205         * 
206         * @param operand
207         *            the value to add
208         * @throws NullPointerException
209         *             if the object is null
210         *
211         * @since Commons Lang 2.2
212         */
213        public void add(Number operand) {
214            this.value += operand.doubleValue();
215        }
216    
217        /**
218         * Subtracts a value.
219         * 
220         * @param operand
221         *            the value to add
222         *
223         * @since Commons Lang 2.2
224         */
225        public void subtract(double operand) {
226            this.value -= operand;
227        }
228    
229        /**
230         * Subtracts a value.
231         * 
232         * @param operand
233         *            the value to add
234         * @throws NullPointerException
235         *             if the object is null
236         *
237         * @since Commons Lang 2.2
238         */
239        public void subtract(Number operand) {
240            this.value -= operand.doubleValue();
241        }
242    
243        //-----------------------------------------------------------------------
244        /**
245         * Compares this object against the specified object. The result is <code>true</code> if and only if the argument
246         * is not <code>null</code> and is a <code>Double</code> object that represents a double that has the identical
247         * bit pattern to the bit pattern of the double represented by this object. For this purpose, two
248         * <code>double</code> values are considered to be the same if and only if the method
249         * {@link Double#doubleToLongBits(double)}returns the same long value when applied to each.
250         * <p>
251         * Note that in most cases, for two instances of class <code>Double</code>,<code>d1</code> and <code>d2</code>,
252         * the value of <code>d1.equals(d2)</code> is <code>true</code> if and only if <blockquote>
253         * 
254         * <pre>
255         *   d1.doubleValue()&nbsp;== d2.doubleValue()
256         * </pre>
257         * 
258         * </blockquote>
259         * <p>
260         * also has the value <code>true</code>. However, there are two exceptions:
261         * <ul>
262         * <li>If <code>d1</code> and <code>d2</code> both represent <code>Double.NaN</code>, then the
263         * <code>equals</code> method returns <code>true</code>, even though <code>Double.NaN==Double.NaN</code> has
264         * the value <code>false</code>.
265         * <li>If <code>d1</code> represents <code>+0.0</code> while <code>d2</code> represents <code>-0.0</code>,
266         * or vice versa, the <code>equal</code> test has the value <code>false</code>, even though
267         * <code>+0.0==-0.0</code> has the value <code>true</code>. This allows hashtables to operate properly.
268         * </ul>
269         * 
270         * @param obj
271         *            the object to compare with.
272         * @return <code>true</code> if the objects are the same; <code>false</code> otherwise.
273         */
274        public boolean equals(Object obj) {
275            return (obj instanceof MutableDouble)
276                && (Double.doubleToLongBits(((MutableDouble) obj).value) == Double.doubleToLongBits(value));
277        }
278    
279        /**
280         * Returns a suitable hashcode for this mutable.
281         * 
282         * @return a suitable hashcode
283         */
284        public int hashCode() {
285            long bits = Double.doubleToLongBits(value);
286            return (int) (bits ^ (bits >>> 32));
287        }
288    
289        /**
290         * Compares this mutable to another in ascending order.
291         * 
292         * @param obj
293         *            the mutable to compare to
294         * @return negative if this is less, zero if equal, positive if greater
295         * @throws ClassCastException if the argument is not a MutableDouble
296         */
297        public int compareTo(Object obj) {
298            MutableDouble other = (MutableDouble) obj;
299            double anotherVal = other.value;
300            return NumberUtils.compare(value, anotherVal);
301        }
302    
303        /**
304         * Returns the String value of this mutable.
305         * 
306         * @return the mutable value as a string
307         */
308        public String toString() {
309            return String.valueOf(value);
310        }
311    
312    }