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