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 *
024 * @see Float
025 * @since 2.1
026 */
027public class MutableFloat extends Number implements Comparable<MutableFloat>, Mutable<Number> {
028
029    /**
030     * Required for serialization support.
031     *
032     * @see java.io.Serializable
033     */
034    private static final long serialVersionUID = 5787169186L;
035
036    /** The mutable value. */
037    private float value;
038
039    /**
040     * Constructs a new MutableFloat with the default value of zero.
041     */
042    public MutableFloat() {
043        super();
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        super();
053        this.value = value;
054    }
055
056    /**
057     * Constructs a new MutableFloat 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 MutableFloat(final Number value) {
063        super();
064        this.value = value.floatValue();
065    }
066
067    /**
068     * Constructs a new MutableFloat 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 float
072     * @since 2.5
073     */
074    public MutableFloat(final String value) {
075        super();
076        this.value = Float.parseFloat(value);
077    }
078
079    //-----------------------------------------------------------------------
080    /**
081     * Gets the value as a Float instance.
082     *
083     * @return the value as a Float, never null
084     */
085    @Override
086    public Float getValue() {
087        return Float.valueOf(this.value);
088    }
089
090    /**
091     * Sets the value.
092     *
093     * @param value  the value to set
094     */
095    public void setValue(final float 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.floatValue();
108    }
109
110    //-----------------------------------------------------------------------
111    /**
112     * Checks whether the float value is the special NaN value.
113     *
114     * @return true if NaN
115     */
116    public boolean isNaN() {
117        return Float.isNaN(value);
118    }
119
120    /**
121     * Checks whether the float value is infinite.
122     *
123     * @return true if infinite
124     */
125    public boolean isInfinite() {
126        return Float.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 float getAndIncrement() {
147        final float 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 float 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 float getAndDecrement() {
181        final float 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 float 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, not null
203     * @since 2.2
204     */
205    public void add(final float 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.floatValue();
218    }
219
220    /**
221     * Subtracts a value from the value of this instance.
222     *
223     * @param operand  the value to subtract
224     * @since 2.2
225     */
226    public void subtract(final float 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.floatValue();
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 float addAndGet(final float 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 float addAndGet(final Number operand) {
264        this.value += operand.floatValue();
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 float getAndAdd(final float operand) {
277        final float 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 float getAndAdd(final Number operand) {
292        final float last = value;
293        this.value += operand.floatValue();
294        return last;
295    }
296
297    //-----------------------------------------------------------------------
298    // shortValue and byteValue rely on Number implementation
299    /**
300     * Returns the value of this MutableFloat 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 MutableFloat 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 MutableFloat 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 value;
327    }
328
329    /**
330     * Returns the value of this MutableFloat 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 Float.
342     *
343     * @return a Float instance containing the value from this mutable, never null
344     */
345    public Float toFloat() {
346        return Float.valueOf(floatValue());
347    }
348
349    //-----------------------------------------------------------------------
350    /**
351     * Compares this object against some other object. The result is {@code true} if and only if the argument is
352     * not {@code null} and is a {@code Float} object that represents a {@code float} that has the
353     * identical bit pattern to the bit pattern of the {@code float} represented by this object. For this
354     * purpose, two float values are considered to be the same if and only if the method
355     * {@link Float#floatToIntBits(float)}returns the same int value when applied to each.
356     * <p>
357     * Note that in most cases, for two instances of class {@code Float},{@code f1} and {@code f2},
358     * the value of {@code f1.equals(f2)} is {@code true} if and only if <blockquote>
359     *
360     * <pre>
361     *   f1.floatValue() == f2.floatValue()
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 f1} and {@code f2} both represent {@code Float.NaN}, then the
369     * {@code equals} method returns {@code true}, even though {@code Float.NaN==Float.NaN} has
370     * the value {@code false}.
371     * <li>If {@code f1} represents {@code +0.0f} while {@code f2} represents {@code -0.0f},
372     * or vice versa, the {@code equal} test has the value {@code false}, even though
373     * {@code 0.0f==-0.0f} has the value {@code true}.
374     * </ul>
375     * This definition allows hashtables to operate properly.
376     *
377     * @param obj  the object to compare with, null returns false
378     * @return {@code true} if the objects are the same; {@code false} otherwise.
379     * @see java.lang.Float#floatToIntBits(float)
380     */
381    @Override
382    public boolean equals(final Object obj) {
383        return obj instanceof MutableFloat
384            && Float.floatToIntBits(((MutableFloat) obj).value) == Float.floatToIntBits(value);
385    }
386
387    /**
388     * Returns a suitable hash code for this mutable.
389     *
390     * @return a suitable hash code
391     */
392    @Override
393    public int hashCode() {
394        return Float.floatToIntBits(value);
395    }
396
397    //-----------------------------------------------------------------------
398    /**
399     * Compares this mutable to another in ascending order.
400     *
401     * @param other  the other mutable to compare to, not null
402     * @return negative if this is less, zero if equal, positive if greater
403     */
404    @Override
405    public int compareTo(final MutableFloat other) {
406        return Float.compare(this.value, other.value);
407    }
408
409    //-----------------------------------------------------------------------
410    /**
411     * Returns the String value of this mutable.
412     *
413     * @return the mutable value as a string
414     */
415    @Override
416    public String toString() {
417        return String.valueOf(value);
418    }
419
420}