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 float} wrapper.
021 * <p>
022 * Note that as MutableFloat does not extend Float, it is not treated by String.format as a Float parameter.
023 * </p>
024 *
025 * @see Float
026 * @since 2.1
027 */
028public class MutableFloat extends Number implements Comparable<MutableFloat>, Mutable<Number> {
029
030    /**
031     * Required for serialization support.
032     *
033     * @see java.io.Serializable
034     */
035    private static final long serialVersionUID = 5787169186L;
036
037    /** The mutable value. */
038    private float value;
039
040    /**
041     * Constructs a new MutableFloat with the default value of zero.
042     */
043    public MutableFloat() {
044    }
045
046    /**
047     * Constructs a new MutableFloat with the specified value.
048     *
049     * @param value  the initial value to store
050     */
051    public MutableFloat(final float value) {
052        this.value = value;
053    }
054
055    /**
056     * Constructs a new MutableFloat 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 MutableFloat(final Number value) {
062        this.value = value.floatValue();
063    }
064
065    /**
066     * Constructs a new MutableFloat 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 float
070     * @since 2.5
071     */
072    public MutableFloat(final String value) {
073        this.value = Float.parseFloat(value);
074    }
075
076    /**
077     * Gets the value as a Float instance.
078     *
079     * @return the value as a Float, never null
080     */
081    @Override
082    public Float getValue() {
083        return Float.valueOf(this.value);
084    }
085
086    /**
087     * Sets the value.
088     *
089     * @param value  the value to set
090     */
091    public void setValue(final float 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.floatValue();
104    }
105
106    /**
107     * Checks whether the float value is the special NaN value.
108     *
109     * @return true if NaN
110     */
111    public boolean isNaN() {
112        return Float.isNaN(value);
113    }
114
115    /**
116     * Checks whether the float value is infinite.
117     *
118     * @return true if infinite
119     */
120    public boolean isInfinite() {
121        return Float.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 float getAndIncrement() {
141        final float 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 float 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 float getAndDecrement() {
175        final float 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 float 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, not null
196     * @since 2.2
197     */
198    public void add(final float 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.floatValue();
211    }
212
213    /**
214     * Subtracts a value from the value of this instance.
215     *
216     * @param operand  the value to subtract
217     * @since 2.2
218     */
219    public void subtract(final float 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.floatValue();
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 float addAndGet(final float 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 float addAndGet(final Number operand) {
257        this.value += operand.floatValue();
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 float getAndAdd(final float operand) {
270        final float 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 float getAndAdd(final Number operand) {
285        final float last = value;
286        this.value += operand.floatValue();
287        return last;
288    }
289
290    // shortValue and byteValue rely on Number implementation
291    /**
292     * Returns the value of this MutableFloat 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 MutableFloat 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 MutableFloat 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 value;
319    }
320
321    /**
322     * Returns the value of this MutableFloat 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 Float.
333     *
334     * @return a Float instance containing the value from this mutable, never null
335     */
336    public Float toFloat() {
337        return Float.valueOf(floatValue());
338    }
339
340    /**
341     * Compares this object against some other object. The result is {@code true} if and only if the argument is
342     * not {@code null} and is a {@link Float} object that represents a {@code float} that has the
343     * identical bit pattern to the bit pattern of the {@code float} represented by this object. For this
344     * purpose, two float values are considered to be the same if and only if the method
345     * {@link Float#floatToIntBits(float)}returns the same int value when applied to each.
346     * <p>
347     * Note that in most cases, for two instances of class {@link Float},{@code f1} and {@code f2},
348     * the value of {@code f1.equals(f2)} is {@code true} if and only if <blockquote>
349     *
350     * <pre>
351     *   f1.floatValue() == f2.floatValue()
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 f1} and {@code f2} both represent {@code Float.NaN}, then the
359     * {@code equals} method returns {@code true}, even though {@code Float.NaN==Float.NaN} has
360     * the value {@code false}.
361     * <li>If {@code f1} represents {@code +0.0f} while {@code f2} represents {@code -0.0f},
362     * or vice versa, the {@code equal} test has the value {@code false}, even though
363     * {@code 0.0f==-0.0f} has the value {@code true}.
364     * </ul>
365     * This definition allows hashtables to operate properly.
366     *
367     * @param obj  the object to compare with, null returns false
368     * @return {@code true} if the objects are the same; {@code false} otherwise.
369     * @see Float#floatToIntBits(float)
370     */
371    @Override
372    public boolean equals(final Object obj) {
373        return obj instanceof MutableFloat
374            && Float.floatToIntBits(((MutableFloat) obj).value) == Float.floatToIntBits(value);
375    }
376
377    /**
378     * Returns a suitable hash code for this mutable.
379     *
380     * @return a suitable hash code
381     */
382    @Override
383    public int hashCode() {
384        return Float.floatToIntBits(value);
385    }
386
387    /**
388     * Compares this mutable to another in ascending order.
389     *
390     * @param other  the other mutable to compare to, not null
391     * @return negative if this is less, zero if equal, positive if greater
392     */
393    @Override
394    public int compareTo(final MutableFloat other) {
395        return Float.compare(this.value, other.value);
396    }
397
398    /**
399     * Returns the String value of this mutable.
400     *
401     * @return the mutable value as a string
402     */
403    @Override
404    public String toString() {
405        return String.valueOf(value);
406    }
407
408}