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