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     * @author Apache Software Foundation
027     * @version $Id: MutableDouble.java 905707 2010-02-02 16:59:59Z niallp $
028     */
029    public class MutableDouble extends Number implements Comparable, Mutable {
030    
031        /**
032         * Required for serialization support.
033         * 
034         * @see java.io.Serializable
035         */
036        private static final long serialVersionUID = 1587163916L;
037    
038        /** The mutable value. */
039        private double value;
040    
041        /**
042         * Constructs a new MutableDouble with the default value of zero.
043         */
044        public MutableDouble() {
045            super();
046        }
047    
048        /**
049         * Constructs a new MutableDouble with the specified value.
050         * 
051         * @param value  the initial value to store
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  the initial value to store, not null
062         * @throws NullPointerException if the object is null
063         */
064        public MutableDouble(Number value) {
065            super();
066            this.value = value.doubleValue();
067        }
068    
069        /**
070         * Constructs a new MutableDouble parsing the given string.
071         * 
072         * @param value  the string to parse, not null
073         * @throws NumberFormatException if the string cannot be parsed into a double
074         * @since 2.5
075         */
076        public MutableDouble(String value) throws NumberFormatException {
077            super();
078            this.value = Double.parseDouble(value);
079        }
080    
081        //-----------------------------------------------------------------------
082        /**
083         * Gets the value as a Double instance.
084         * 
085         * @return the value as a Double, never null
086         */
087        public Object getValue() {
088            return new Double(this.value);
089        }
090    
091        /**
092         * Sets the value.
093         * 
094         * @param value  the value to set
095         */
096        public void setValue(double value) {
097            this.value = value;
098        }
099    
100        /**
101         * Sets the value from any Number instance.
102         * 
103         * @param value  the value to set, not null
104         * @throws NullPointerException if the object is null
105         * @throws ClassCastException if the type is not a {@link Number}
106         */
107        public void setValue(Object value) {
108            setValue(((Number) value).doubleValue());
109        }
110    
111        //-----------------------------------------------------------------------
112        /**
113         * Checks whether the double value is the special NaN value.
114         * 
115         * @return true if NaN
116         */
117        public boolean isNaN() {
118            return Double.isNaN(value);
119        }
120    
121        /**
122         * Checks whether the double value is infinite.
123         * 
124         * @return true if infinite
125         */
126        public boolean isInfinite() {
127            return Double.isInfinite(value);
128        }
129    
130        //-----------------------------------------------------------------------
131        /**
132         * Increments the value.
133         *
134         * @since Commons Lang 2.2
135         */
136        public void increment() {
137            value++;
138        }
139    
140        /**
141         * Decrements the value.
142         *
143         * @since Commons Lang 2.2
144         */
145        public void decrement() {
146            value--;
147        }
148    
149        //-----------------------------------------------------------------------
150        /**
151         * Adds a value to the value of this instance.
152         * 
153         * @param operand  the value to add
154         * @since Commons Lang 2.2
155         */
156        public void add(double operand) {
157            this.value += operand;
158        }
159    
160        /**
161         * Adds a value to the value of this instance.
162         * 
163         * @param operand  the value to add, not null
164         * @throws NullPointerException if the object is null
165         * @since Commons Lang 2.2
166         */
167        public void add(Number operand) {
168            this.value += operand.doubleValue();
169        }
170    
171        /**
172         * Subtracts a value from the value of this instance.
173         * 
174         * @param operand  the value to subtract, not null
175         * @since Commons Lang 2.2
176         */
177        public void subtract(double operand) {
178            this.value -= operand;
179        }
180    
181        /**
182         * Subtracts a value from the value of this instance.
183         * 
184         * @param operand  the value to subtract, not null
185         * @throws NullPointerException if the object is null
186         * @since Commons Lang 2.2
187         */
188        public void subtract(Number operand) {
189            this.value -= operand.doubleValue();
190        }
191    
192        //-----------------------------------------------------------------------
193        // shortValue and bytValue rely on Number implementation
194        /**
195         * Returns the value of this MutableDouble as an int.
196         *
197         * @return the numeric value represented by this object after conversion to type int.
198         */
199        public int intValue() {
200            return (int) value;
201        }
202    
203        /**
204         * Returns the value of this MutableDouble as a long.
205         *
206         * @return the numeric value represented by this object after conversion to type long.
207         */
208        public long longValue() {
209            return (long) value;
210        }
211    
212        /**
213         * Returns the value of this MutableDouble as a float.
214         *
215         * @return the numeric value represented by this object after conversion to type float.
216         */
217        public float floatValue() {
218            return (float) value;
219        }
220    
221        /**
222         * Returns the value of this MutableDouble as a double.
223         *
224         * @return the numeric value represented by this object after conversion to type double.
225         */
226        public double doubleValue() {
227            return value;
228        }
229    
230        //-----------------------------------------------------------------------
231        /**
232         * Gets this mutable as an instance of Double.
233         *
234         * @return a Double instance containing the value from this mutable, never null
235         */
236        public Double toDouble() {
237            return new Double(doubleValue());
238        }
239    
240        //-----------------------------------------------------------------------
241        /**
242         * Compares this object against the specified object. The result is <code>true</code> if and only if the argument
243         * is not <code>null</code> and is a <code>Double</code> object that represents a double that has the identical
244         * bit pattern to the bit pattern of the double represented by this object. For this purpose, two
245         * <code>double</code> values are considered to be the same if and only if the method
246         * {@link Double#doubleToLongBits(double)}returns the same long value when applied to each.
247         * <p>
248         * Note that in most cases, for two instances of class <code>Double</code>,<code>d1</code> and <code>d2</code>,
249         * the value of <code>d1.equals(d2)</code> is <code>true</code> if and only if <blockquote>
250         * 
251         * <pre>
252         *   d1.doubleValue()&nbsp;== d2.doubleValue()
253         * </pre>
254         * 
255         * </blockquote>
256         * <p>
257         * also has the value <code>true</code>. However, there are two exceptions:
258         * <ul>
259         * <li>If <code>d1</code> and <code>d2</code> both represent <code>Double.NaN</code>, then the
260         * <code>equals</code> method returns <code>true</code>, even though <code>Double.NaN==Double.NaN</code> has
261         * the value <code>false</code>.
262         * <li>If <code>d1</code> represents <code>+0.0</code> while <code>d2</code> represents <code>-0.0</code>,
263         * or vice versa, the <code>equal</code> test has the value <code>false</code>, even though
264         * <code>+0.0==-0.0</code> has the value <code>true</code>. This allows hashtables to operate properly.
265         * </ul>
266         * 
267         * @param obj  the object to compare with, null returns false
268         * @return <code>true</code> if the objects are the same; <code>false</code> otherwise.
269         */
270        public boolean equals(Object obj) {
271            return (obj instanceof MutableDouble)
272                && (Double.doubleToLongBits(((MutableDouble) obj).value) == Double.doubleToLongBits(value));
273        }
274    
275        /**
276         * Returns a suitable hash code for this mutable.
277         * 
278         * @return a suitable hash code
279         */
280        public int hashCode() {
281            long bits = Double.doubleToLongBits(value);
282            return (int) (bits ^ (bits >>> 32));
283        }
284    
285        //-----------------------------------------------------------------------
286        /**
287         * Compares this mutable to another in ascending order.
288         * 
289         * @param obj the other mutable to compare to, not null
290         * @return negative if this is less, zero if equal, positive if greater
291         * @throws ClassCastException if the argument is not a MutableDouble
292         */
293        public int compareTo(Object obj) {
294            MutableDouble other = (MutableDouble) obj;
295            double anotherVal = other.value;
296            return NumberUtils.compare(value, anotherVal);
297        }
298    
299        //-----------------------------------------------------------------------
300        /**
301         * Returns the String value of this mutable.
302         * 
303         * @return the mutable value as a string
304         */
305        public String toString() {
306            return String.valueOf(value);
307        }
308    
309    }