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 float} 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 MutableFloat does not extend Float, it is not treated by String.format as a Float parameter.
029 * </p>
030 *
031 * @see Float
032 * @see DoubleAccumulator
033 * @see DoubleAdder
034 * @since 2.1
035 */
036public class MutableFloat extends Number implements Comparable<MutableFloat>, Mutable<Number> {
037
038    /**
039     * Required for serialization support.
040     *
041     * @see java.io.Serializable
042     */
043    private static final long serialVersionUID = 5787169186L;
044
045    /** The mutable value. */
046    private float value;
047
048    /**
049     * Constructs a new MutableFloat with the default value of zero.
050     */
051    public MutableFloat() {
052    }
053
054    /**
055     * Constructs a new MutableFloat with the specified value.
056     *
057     * @param value  the initial value to store.
058     */
059    public MutableFloat(final float value) {
060        this.value = value;
061    }
062
063    /**
064     * Constructs a new MutableFloat 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 MutableFloat(final Number value) {
070        this.value = value.floatValue();
071    }
072
073    /**
074     * Constructs a new MutableFloat 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 float, see {@link Float#parseFloat(String)}.
078     * @since 2.5
079     */
080    public MutableFloat(final String value) {
081        this.value = Float.parseFloat(value);
082    }
083
084    /**
085     * Adds a value to the value of this instance.
086     *
087     * @param operand  the value to add, not null.
088     * @since 2.2
089     */
090    public void add(final float 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.floatValue();
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 float addAndGet(final float 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 float addAndGet(final Number operand) {
128        this.value += operand.floatValue();
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 MutableFloat other) {
140        return Float.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 float decrementAndGet() {
160        value--;
161        return value;
162    }
163
164    /**
165     * Returns the value of this MutableFloat 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 some other object. The result is {@code true} if and only if the argument is not {@code null} and is a {@link Float} object
176     * that represents a {@code float} that has the identical bit pattern to the bit pattern of the {@code float} represented by this object. For this purpose,
177     * two float values are considered to be the same if and only if the method {@link Float#floatToIntBits(float)}returns the same int value when applied to
178     * each.
179     * <p>
180     * Note that in most cases, for two instances of class {@link Float},{@code f1} and {@code f2}, the value of {@code f1.equals(f2)} is {@code true} if and
181     * only if:
182     * </p>
183     * <pre>
184     * f1.floatValue() == f2.floatValue()
185     * </pre>
186     * <p>
187     * also has the value {@code true}. However, there are two exceptions:
188     * </p>
189     * <ul>
190     * <li>If {@code f1} and {@code f2} both represent {@code Float.NaN}, then the {@code equals} method returns {@code true}, even though
191     * {@code Float.NaN == Float.NaN} has the value {@code false}.
192     * <li>If {@code f1} represents {@code +0.0f} while {@code f2} represents {@code -0.0f}, or vice versa, the {@code equal} test has the value {@code false},
193     * even though {@code 0.0f == -0.0f} has the value {@code true}.
194     * </ul>
195     * <p>
196     * This definition allows hashtables to operate properly.
197     * </p>
198     *
199     * @param obj the object to compare with, null returns false.
200     * @return {@code true} if the objects are the same; {@code false} otherwise.
201     * @see Float#floatToIntBits(float)
202     */
203    @Override
204    public boolean equals(final Object obj) {
205        return obj instanceof MutableFloat
206            && Float.floatToIntBits(((MutableFloat) obj).value) == Float.floatToIntBits(value);
207    }
208
209    /**
210     * Returns the value of this MutableFloat as a float.
211     *
212     * @return the numeric value represented by this object after conversion to type float.
213     */
214    @Override
215    public float floatValue() {
216        return value;
217    }
218
219    /**
220     * Increments this instance's value by {@code operand}; this method returns the value associated with the instance
221     * immediately prior to the addition operation. This method is not thread safe.
222     *
223     * @param operand the quantity to add, not null.
224     * @return the value associated with this instance immediately before the operand was added.
225     * @since 3.5
226     */
227    public float getAndAdd(final float operand) {
228        final float last = value;
229        this.value += operand;
230        return last;
231    }
232
233    /**
234     * Increments this instance's value by {@code operand}; this method returns the value associated with the instance
235     * immediately prior to the addition operation. This method is not thread safe.
236     *
237     * @param operand the quantity to add, not null.
238     * @throws NullPointerException if {@code operand} is null.
239     * @return the value associated with this instance immediately before the operand was added.
240     * @since 3.5
241     */
242    public float getAndAdd(final Number operand) {
243        final float last = value;
244        this.value += operand.floatValue();
245        return last;
246    }
247
248    /**
249     * Decrements this instance's value by 1; this method returns the value associated with the instance
250     * immediately prior to the decrement operation. This method is not thread safe.
251     *
252     * @return the value associated with the instance before it was decremented.
253     * @since 3.5
254     */
255    public float getAndDecrement() {
256        final float last = value;
257        value--;
258        return last;
259    }
260
261    /**
262     * Increments this instance's value by 1; this method returns the value associated with the instance
263     * immediately prior to the increment operation. This method is not thread safe.
264     *
265     * @return the value associated with the instance before it was incremented.
266     * @since 3.5
267     */
268    public float getAndIncrement() {
269        final float last = value;
270        value++;
271        return last;
272    }
273
274    /**
275     * Gets the value as a Float instance.
276     *
277     * @return the value as a Float, never null.
278     * @deprecated Use {@link #get()}.
279     */
280    @Deprecated
281    @Override
282    public Float getValue() {
283        return Float.valueOf(this.value);
284    }
285
286    /**
287     * Returns a suitable hash code for this mutable.
288     *
289     * @return a suitable hash code.
290     */
291    @Override
292    public int hashCode() {
293        return Float.floatToIntBits(value);
294    }
295
296    /**
297     * Increments the value.
298     *
299     * @since 2.2
300     */
301    public void increment() {
302        value++;
303    }
304
305    /**
306     * Increments this instance's value by 1; this method returns the value associated with the instance
307     * immediately after the increment operation. This method is not thread safe.
308     *
309     * @return the value associated with the instance after it is incremented.
310     * @since 3.5
311     */
312    public float incrementAndGet() {
313        value++;
314        return value;
315    }
316
317    // shortValue and byteValue rely on Number implementation
318    /**
319     * Returns the value of this MutableFloat as an int.
320     *
321     * @return the numeric value represented by this object after conversion to type int.
322     */
323    @Override
324    public int intValue() {
325        return (int) value;
326    }
327
328    /**
329     * Checks whether the float value is infinite.
330     *
331     * @return true if infinite
332     */
333    public boolean isInfinite() {
334        return Float.isInfinite(value);
335    }
336
337    /**
338     * Checks whether the float value is the special NaN value.
339     *
340     * @return true if NaN.
341     */
342    public boolean isNaN() {
343        return Float.isNaN(value);
344    }
345
346    /**
347     * Returns the value of this MutableFloat as a long.
348     *
349     * @return the numeric value represented by this object after conversion to type long.
350     */
351    @Override
352    public long longValue() {
353        return (long) value;
354    }
355
356    /**
357     * Sets the value.
358     *
359     * @param value  the value to set.
360     */
361    public void setValue(final float value) {
362        this.value = value;
363    }
364
365    /**
366     * Sets the value from any Number instance.
367     *
368     * @param value  the value to set, not null.
369     * @throws NullPointerException if the object is null.
370     */
371    @Override
372    public void setValue(final Number value) {
373        this.value = value.floatValue();
374    }
375
376    /**
377     * Subtracts a value from the value of this instance.
378     *
379     * @param operand  the value to subtract.
380     * @since 2.2
381     */
382    public void subtract(final float operand) {
383        this.value -= operand;
384    }
385
386    /**
387     * Subtracts a value from the value of this instance.
388     *
389     * @param operand  the value to subtract, not null.
390     * @throws NullPointerException if the object is null.
391     * @since 2.2
392     */
393    public void subtract(final Number operand) {
394        this.value -= operand.floatValue();
395    }
396
397    /**
398     * Gets this mutable as an instance of Float.
399     *
400     * @return a Float instance containing the value from this mutable, never null.
401     */
402    public Float toFloat() {
403        return Float.valueOf(floatValue());
404    }
405
406    /**
407     * Returns the String value of this mutable.
408     *
409     * @return the mutable value as a string.
410     */
411    @Override
412    public String toString() {
413        return String.valueOf(value);
414    }
415
416}