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