    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 *
    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) {
    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 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        final 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 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        final 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 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 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 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 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        final 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        final 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} if and only if the argument
    352     * is not {@code null} and is a {@code Double} 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} 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 d1} and {@code d2},
    358     * the value of {@code d1.equals(d2)} is {@code true} 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}. However, there are two exceptions:
    367     * <ul>
    368     * <li>If {@code d1} and {@code d2} both represent {@code Double.NaN}, then the
    369     * {@code equals} method returns {@code true}, even though {@code Double.NaN==Double.NaN} has
    370     * the value {@code false}.
    371     * <li>If {@code d1} represents {@code +0.0} while {@code d2} represents {@code -0.0},
    372     * or vice versa, the {@code equal} test has the value {@code false}, even though
    373     * {@code +0.0==-0.0} has the value {@code true}. This allows hashtables to operate properly.
    374     * </ul>
    375     *
    376     * @param obj  the object to compare with, null returns false
    377     * @return {@code true} if the objects are the same; {@code false} 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}