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 */
017package org.apache.commons.lang3.mutable;
018
019/**
020 * A mutable <code>double</code> wrapper.
021 * <p>
022 * Note that as MutableDouble does not extend Double, it is not treated by String.format as a Double parameter. 
023 * 
024 * @see Double
025 * @since 2.1
026 */
027public class MutableDouble extends Number implements Comparable<MutableDouble>, Mutable<Number> {
028
029    /**
030     * Required for serialization support.
031     * 
032     * @see java.io.Serializable
033     */
034    private static final long serialVersionUID = 1587163916L;
035
036    /** The mutable value. */
037    private double value;
038
039    /**
040     * Constructs a new MutableDouble with the default value of zero.
041     */
042    public MutableDouble() {
043        super();
044    }
045
046    /**
047     * Constructs a new MutableDouble with the specified value.
048     * 
049     * @param value  the initial value to store
050     */
051    public MutableDouble(final double value) {
052        super();
053        this.value = value;
054    }
055
056    /**
057     * Constructs a new MutableDouble with the specified value.
058     * 
059     * @param value  the initial value to store, not null
060     * @throws NullPointerException if the object is null
061     */
062    public MutableDouble(final Number value) {
063        super();
064        this.value = value.doubleValue();
065    }
066
067    /**
068     * Constructs a new MutableDouble parsing the given string.
069     * 
070     * @param value  the string to parse, not null
071     * @throws NumberFormatException if the string cannot be parsed into a double
072     * @since 2.5
073     */
074    public MutableDouble(final String value) throws NumberFormatException {
075        super();
076        this.value = Double.parseDouble(value);
077    }
078
079    //-----------------------------------------------------------------------
080    /**
081     * Gets the value as a Double instance.
082     * 
083     * @return the value as a Double, never null
084     */
085    @Override
086    public Double getValue() {
087        return Double.valueOf(this.value);
088    }
089
090    /**
091     * Sets the value.
092     * 
093     * @param value  the value to set
094     */
095    public void setValue(final double value) {
096        this.value = value;
097    }
098
099    /**
100     * Sets the value from any Number instance.
101     * 
102     * @param value  the value to set, not null
103     * @throws NullPointerException if the object is null
104     */
105    @Override
106    public void setValue(final Number value) {
107        this.value = value.doubleValue();
108    }
109
110    //-----------------------------------------------------------------------
111    /**
112     * Checks whether the double value is the special NaN value.
113     * 
114     * @return true if NaN
115     */
116    public boolean isNaN() {
117        return Double.isNaN(value);
118    }
119
120    /**
121     * Checks whether the double value is infinite.
122     * 
123     * @return true if infinite
124     */
125    public boolean isInfinite() {
126        return Double.isInfinite(value);
127    }
128
129    //-----------------------------------------------------------------------
130    /**
131     * Increments the value.
132     *
133     * @since Commons Lang 2.2
134     */
135    public void increment() {
136        value++;
137    }
138
139    /**
140     * Increments this instance's value by 1; this method returns the value associated with the instance
141     * immediately prior to the increment operation. This method is not thread safe.
142     *
143     * @return the value associated with the instance before it was incremented
144     * @since 3.5
145     */
146    public double getAndIncrement() {
147        double last = value;
148        value++;
149        return last;
150    }
151
152    /**
153     * Increments this instance's value by 1; this method returns the value associated with the instance
154     * immediately after the increment operation. This method is not thread safe.
155     *
156     * @return the value associated with the instance after it is incremented
157     * @since 3.5
158     */
159    public double incrementAndGet() {
160        value++;
161        return value;
162    }
163
164    /**
165     * Decrements the value.
166     *
167     * @since Commons Lang 2.2
168     */
169    public void decrement() {
170        value--;
171    }
172
173    /**
174     * Decrements this instance's value by 1; this method returns the value associated with the instance
175     * immediately prior to the decrement operation. This method is not thread safe.
176     *
177     * @return the value associated with the instance before it was decremented
178     * @since 3.5
179     */
180    public double getAndDecrement() {
181        double last = value;
182        value--;
183        return last;
184    }
185
186    /**
187     * Decrements this instance's value by 1; this method returns the value associated with the instance
188     * immediately after the decrement operation. This method is not thread safe.
189     *
190     * @return the value associated with the instance after it is decremented
191     * @since 3.5
192     */
193    public double decrementAndGet() {
194        value--;
195        return value;
196    }
197
198    //-----------------------------------------------------------------------
199    /**
200     * Adds a value to the value of this instance.
201     * 
202     * @param operand  the value to add
203     * @since Commons Lang 2.2
204     */
205    public void add(final double operand) {
206        this.value += operand;
207    }
208
209    /**
210     * Adds a value to the value of this instance.
211     * 
212     * @param operand  the value to add, not null
213     * @throws NullPointerException if the object is null
214     * @since Commons Lang 2.2
215     */
216    public void add(final Number operand) {
217        this.value += operand.doubleValue();
218    }
219
220    /**
221     * Subtracts a value from the value of this instance.
222     * 
223     * @param operand  the value to subtract, not null
224     * @since Commons Lang 2.2
225     */
226    public void subtract(final double operand) {
227        this.value -= operand;
228    }
229
230    /**
231     * Subtracts a value from the value of this instance.
232     * 
233     * @param operand  the value to subtract, not null
234     * @throws NullPointerException if the object is null
235     * @since Commons Lang 2.2
236     */
237    public void subtract(final Number operand) {
238        this.value -= operand.doubleValue();
239    }
240
241    /**
242     * Increments this instance's value by {@code operand}; this method returns the value associated with the instance
243     * immediately after the addition operation. This method is not thread safe.
244     *
245     * @param operand the quantity to add, not null
246     * @return the value associated with this instance after adding the operand
247     * @since 3.5
248     */
249    public double addAndGet(final double operand) {
250        this.value += operand;
251        return value;
252    }
253
254    /**
255     * Increments this instance's value by {@code operand}; this method returns the value associated with the instance
256     * immediately after the addition operation. This method is not thread safe.
257     *
258     * @param operand the quantity to add, not null
259     * @throws NullPointerException if {@code operand} is null
260     * @return the value associated with this instance after adding the operand
261     * @since 3.5
262     */
263    public double addAndGet(final Number operand) {
264        this.value += operand.doubleValue();
265        return value;
266    }
267
268    /**
269     * Increments this instance's value by {@code operand}; this method returns the value associated with the instance
270     * immediately prior to the addition operation. This method is not thread safe.
271     *
272     * @param operand the quantity to add, not null
273     * @return the value associated with this instance immediately before the operand was added
274     * @since 3.5
275     */
276    public double getAndAdd(final double operand) {
277        double last = value;
278        this.value += operand;
279        return last;
280    }
281
282    /**
283     * Increments this instance's value by {@code operand}; this method returns the value associated with the instance
284     * immediately prior to the addition operation. This method is not thread safe.
285     *
286     * @param operand the quantity to add, not null
287     * @throws NullPointerException if {@code operand} is null
288     * @return the value associated with this instance immediately before the operand was added
289     * @since 3.5
290     */
291    public double getAndAdd(final Number operand) {
292        double last = value;
293        this.value += operand.doubleValue();
294        return last;
295    }
296
297    //-----------------------------------------------------------------------
298    // shortValue and byteValue rely on Number implementation
299    /**
300     * Returns the value of this MutableDouble as an int.
301     *
302     * @return the numeric value represented by this object after conversion to type int.
303     */
304    @Override
305    public int intValue() {
306        return (int) value;
307    }
308
309    /**
310     * Returns the value of this MutableDouble as a long.
311     *
312     * @return the numeric value represented by this object after conversion to type long.
313     */
314    @Override
315    public long longValue() {
316        return (long) value;
317    }
318
319    /**
320     * Returns the value of this MutableDouble as a float.
321     *
322     * @return the numeric value represented by this object after conversion to type float.
323     */
324    @Override
325    public float floatValue() {
326        return (float) value;
327    }
328
329    /**
330     * Returns the value of this MutableDouble as a double.
331     *
332     * @return the numeric value represented by this object after conversion to type double.
333     */
334    @Override
335    public double doubleValue() {
336        return value;
337    }
338
339    //-----------------------------------------------------------------------
340    /**
341     * Gets this mutable as an instance of Double.
342     *
343     * @return a Double instance containing the value from this mutable, never null
344     */
345    public Double toDouble() {
346        return Double.valueOf(doubleValue());
347    }
348
349    //-----------------------------------------------------------------------
350    /**
351     * Compares this object against the specified object. The result is <code>true</code> if and only if the argument
352     * is not <code>null</code> and is a <code>Double</code> object that represents a double that has the identical
353     * bit pattern to the bit pattern of the double represented by this object. For this purpose, two
354     * <code>double</code> values are considered to be the same if and only if the method
355     * {@link Double#doubleToLongBits(double)}returns the same long value when applied to each.
356     * <p>
357     * Note that in most cases, for two instances of class <code>Double</code>,<code>d1</code> and <code>d2</code>,
358     * the value of <code>d1.equals(d2)</code> is <code>true</code> if and only if <blockquote>
359     * 
360     * <pre>
361     *   d1.doubleValue()&nbsp;== d2.doubleValue()
362     * </pre>
363     * 
364     * </blockquote>
365     * <p>
366     * also has the value <code>true</code>. However, there are two exceptions:
367     * <ul>
368     * <li>If <code>d1</code> and <code>d2</code> both represent <code>Double.NaN</code>, then the
369     * <code>equals</code> method returns <code>true</code>, even though <code>Double.NaN==Double.NaN</code> has
370     * the value <code>false</code>.
371     * <li>If <code>d1</code> represents <code>+0.0</code> while <code>d2</code> represents <code>-0.0</code>,
372     * or vice versa, the <code>equal</code> test has the value <code>false</code>, even though
373     * <code>+0.0==-0.0</code> has the value <code>true</code>. This allows hashtables to operate properly.
374     * </ul>
375     * 
376     * @param obj  the object to compare with, null returns false
377     * @return <code>true</code> if the objects are the same; <code>false</code> otherwise.
378     */
379    @Override
380    public boolean equals(final Object obj) {
381        return obj instanceof MutableDouble
382            && Double.doubleToLongBits(((MutableDouble) obj).value) == Double.doubleToLongBits(value);
383    }
384
385    /**
386     * Returns a suitable hash code for this mutable.
387     * 
388     * @return a suitable hash code
389     */
390    @Override
391    public int hashCode() {
392        final long bits = Double.doubleToLongBits(value);
393        return (int) (bits ^ bits >>> 32);
394    }
395
396    //-----------------------------------------------------------------------
397    /**
398     * Compares this mutable to another in ascending order.
399     * 
400     * @param other  the other mutable to compare to, not null
401     * @return negative if this is less, zero if equal, positive if greater
402     */
403    @Override
404    public int compareTo(final MutableDouble other) {
405        return Double.compare(this.value, other.value);
406    }
407
408    //-----------------------------------------------------------------------
409    /**
410     * Returns the String value of this mutable.
411     * 
412     * @return the mutable value as a string
413     */
414    @Override
415    public String toString() {
416        return String.valueOf(value);
417    }
418
419}