/* Float.java -- object wrapper for float
   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
   Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package java.lang;

/**
 * Instances of class <code>Float</code> represent primitive
 * <code>float</code> values.
 *
 * Additionally, this class provides various helper functions and variables
 * related to floats.
 *
 * @author Paul Fisher
 * @author Andrew Haley (aph@cygnus.com)
 * @author Eric Blake (ebb9@email.byu.edu)
 * @author Tom Tromey (tromey@redhat.com)
 * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
 * @since 1.0
 * @status partly updated to 1.5
 */
public final class Float extends Number implements Comparable<Float>
{
  /**
   * Compatible with JDK 1.0+.
   */
  private static final long serialVersionUID = -2671257302660747028L;

  /**
   * The maximum positive value a <code>double</code> may represent
   * is 3.4028235e+38f.
   */
  public static final float MAX_VALUE = 3.4028235e+38f;

  /**
   * The minimum positive value a <code>float</code> may represent
   * is 1.4e-45.
   */
  public static final float MIN_VALUE = 1.4e-45f;

  /**
   * The value of a float representation -1.0/0.0, negative infinity.
   */
  public static final float NEGATIVE_INFINITY = -1.0f / 0.0f;

  /**
   * The value of a float representation 1.0/0.0, positive infinity.
   */
  public static final float POSITIVE_INFINITY = 1.0f / 0.0f;

  /**
   * All IEEE 754 values of NaN have the same value in Java.
   */
  public static final float NaN = 0.0f / 0.0f;

  /**
   * The primitive type <code>float</code> is represented by this
   * <code>Class</code> object.
   * @since 1.1
   */
  public static final Class<Float> TYPE = (Class<Float>) VMClassLoader.getPrimitiveClass('F');

  /**
   * The number of bits needed to represent a <code>float</code>.
   * @since 1.5
   */
  public static final int SIZE = 32;

  /**
   * The immutable value of this Float.
   *
   * @serial the wrapped float
   */
  private final float value;

  /**
   * Create a <code>Float</code> from the primitive <code>float</code>
   * specified.
   *
   * @param value the <code>float</code> argument
   */
  public Float(float value)
  {
    this.value = value;
  }

  /**
   * Create a <code>Float</code> from the primitive <code>double</code>
   * specified.
   *
   * @param value the <code>double</code> argument
   */
  public Float(double value)
  {
    this.value = (float) value;
  }

  /**
   * Create a <code>Float</code> from the specified <code>String</code>.
   * This method calls <code>Float.parseFloat()</code>.
   *
   * @param s the <code>String</code> to convert
   * @throws NumberFormatException if <code>s</code> cannot be parsed as a
   *         <code>float</code>
   * @throws NullPointerException if <code>s</code> is null
   * @see #parseFloat(String)
   */
  public Float(String s)
  {
    value = parseFloat(s);
  }

  /**
   * Convert the <code>float</code> to a <code>String</code>.
   * Floating-point string representation is fairly complex: here is a
   * rundown of the possible values.  "<code>[-]</code>" indicates that a
   * negative sign will be printed if the value (or exponent) is negative.
   * "<code>&lt;number&gt;</code>" means a string of digits ('0' to '9').
   * "<code>&lt;digit&gt;</code>" means a single digit ('0' to '9').<br>
   *
   * <table border=1>
   * <tr><th>Value of Float</th><th>String Representation</th></tr>
   * <tr><td>[+-] 0</td> <td><code>[-]0.0</code></td></tr>
   * <tr><td>Between [+-] 10<sup>-3</sup> and 10<sup>7</sup>, exclusive</td>
   *     <td><code>[-]number.number</code></td></tr>
   * <tr><td>Other numeric value</td>
   *     <td><code>[-]&lt;digit&gt;.&lt;number&gt;
   *          E[-]&lt;number&gt;</code></td></tr>
   * <tr><td>[+-] infinity</td> <td><code>[-]Infinity</code></td></tr>
   * <tr><td>NaN</td> <td><code>NaN</code></td></tr>
   * </table>
   *
   * Yes, negative zero <em>is</em> a possible value.  Note that there is
   * <em>always</em> a <code>.</code> and at least one digit printed after
   * it: even if the number is 3, it will be printed as <code>3.0</code>.
   * After the ".", all digits will be printed except trailing zeros. The
   * result is rounded to the shortest decimal number which will parse back
   * to the same float.
   *
   * <p>To create other output formats, use {@link java.text.NumberFormat}.
   *
   * @XXX specify where we are not in accord with the spec.
   *
   * @param f the <code>float</code> to convert
   * @return the <code>String</code> representing the <code>float</code>
   */
  public static String toString(float f)
  {
    return VMFloat.toString(f);
  }

  /**
   * Convert a float value to a hexadecimal string.  This converts as
   * follows:
   * <ul>
   * <li> A NaN value is converted to the string "NaN".
   * <li> Positive infinity is converted to the string "Infinity".
   * <li> Negative infinity is converted to the string "-Infinity".
   * <li> For all other values, the first character of the result is '-'
   * if the value is negative.  This is followed by '0x1.' if the
   * value is normal, and '0x0.' if the value is denormal.  This is
   * then followed by a (lower-case) hexadecimal representation of the
   * mantissa, with leading zeros as required for denormal values.
   * The next character is a 'p', and this is followed by a decimal
   * representation of the unbiased exponent.
   * </ul>
   * @param f the float value
   * @return the hexadecimal string representation
   * @since 1.5
   */
  public static String toHexString(float f)
  {
    if (isNaN(f))
      return "NaN";
    if (isInfinite(f))
      return f < 0 ? "-Infinity" : "Infinity";

    int bits = floatToIntBits(f);
    StringBuilder result = new StringBuilder();
    
    if (bits < 0)
      result.append('-');
    result.append("0x");

    final int mantissaBits = 23;
    final int exponentBits = 8;
    int mantMask = (1 << mantissaBits) - 1;
    int mantissa = bits & mantMask;
    int expMask = (1 << exponentBits) - 1;
    int exponent = (bits >>> mantissaBits) & expMask;

    result.append(exponent == 0 ? '0' : '1');
    result.append('.');
    // For Float only, we have to adjust the mantissa.
    mantissa <<= 1;
    result.append(Integer.toHexString(mantissa));
    if (exponent == 0 && mantissa != 0)
      {
        // Treat denormal specially by inserting '0's to make
        // the length come out right.  The constants here are
        // to account for things like the '0x'.
        int offset = 4 + ((bits < 0) ? 1 : 0);
        // The silly +3 is here to keep the code the same between
        // the Float and Double cases.  In Float the value is
        // not a multiple of 4.
        int desiredLength = offset + (mantissaBits + 3) / 4;
        while (result.length() < desiredLength)
          result.insert(offset, '0');
      }
    result.append('p');
    if (exponent == 0 && mantissa == 0)
      {
        // Zero, so do nothing special.
      }
    else
      {
        // Apply bias.
        boolean denormal = exponent == 0;
        exponent -= (1 << (exponentBits - 1)) - 1;
        // Handle denormal.
        if (denormal)
          ++exponent;
      }

    result.append(Integer.toString(exponent));
    return result.toString();
  }

  /**
   * Creates a new <code>Float</code> object using the <code>String</code>.
   *
   * @param s the <code>String</code> to convert
   * @return the new <code>Float</code>
   * @throws NumberFormatException if <code>s</code> cannot be parsed as a
   *         <code>float</code>
   * @throws NullPointerException if <code>s</code> is null
   * @see #parseFloat(String)
   */
  public static Float valueOf(String s)
  {
    return new Float(parseFloat(s));
  }

  /**
   * Returns a <code>Float</code> object wrapping the value.
   * In contrast to the <code>Float</code> constructor, this method
   * may cache some values.  It is used by boxing conversion.
   *
   * @param val the value to wrap
   * @return the <code>Float</code>
   * @since 1.5
   */
  public static Float valueOf(float val)
  {
    // We don't actually cache, but we could.
    return new Float(val);
  }

  /**
   * Parse the specified <code>String</code> as a <code>float</code>. The
   * extended BNF grammar is as follows:<br>
   * <pre>
   * <em>DecodableString</em>:
   *      ( [ <code>-</code> | <code>+</code> ] <code>NaN</code> )
   *    | ( [ <code>-</code> | <code>+</code> ] <code>Infinity</code> )
   *    | ( [ <code>-</code> | <code>+</code> ] <em>FloatingPoint</em>
   *              [ <code>f</code> | <code>F</code> | <code>d</code>
   *                | <code>D</code>] )
   * <em>FloatingPoint</em>:
   *      ( { <em>Digit</em> }+ [ <code>.</code> { <em>Digit</em> } ]
   *              [ <em>Exponent</em> ] )
   *    | ( <code>.</code> { <em>Digit</em> }+ [ <em>Exponent</em> ] )
   * <em>Exponent</em>:
   *      ( ( <code>e</code> | <code>E</code> )
   *              [ <code>-</code> | <code>+</code> ] { <em>Digit</em> }+ )
   * <em>Digit</em>: <em><code>'0'</code> through <code>'9'</code></em>
   * </pre>
   *
   * <p>NaN and infinity are special cases, to allow parsing of the output
   * of toString.  Otherwise, the result is determined by calculating
   * <em>n * 10<sup>exponent</sup></em> to infinite precision, then rounding
   * to the nearest float. Remember that many numbers cannot be precisely
   * represented in floating point. In case of overflow, infinity is used,
   * and in case of underflow, signed zero is used. Unlike Integer.parseInt,
   * this does not accept Unicode digits outside the ASCII range.
   *
   * <p>If an unexpected character is found in the <code>String</code>, a
   * <code>NumberFormatException</code> will be thrown.  Leading and trailing
   * 'whitespace' is ignored via <code>String.trim()</code>, but spaces
   * internal to the actual number are not allowed.
   *
   * <p>To parse numbers according to another format, consider using
   * {@link java.text.NumberFormat}.
   *
   * @XXX specify where/how we are not in accord with the spec.
   *
   * @param str the <code>String</code> to convert
   * @return the <code>float</code> value of <code>s</code>
   * @throws NumberFormatException if <code>str</code> cannot be parsed as a
   *         <code>float</code>
   * @throws NullPointerException if <code>str</code> is null
   * @see #MIN_VALUE
   * @see #MAX_VALUE
   * @see #POSITIVE_INFINITY
   * @see #NEGATIVE_INFINITY
   * @since 1.2
   */
  public static float parseFloat(String str)
  {
    return VMFloat.parseFloat(str);
  }

  /**
   * Return <code>true</code> if the <code>float</code> has the same
   * value as <code>NaN</code>, otherwise return <code>false</code>.
   *
   * @param v the <code>float</code> to compare
   * @return whether the argument is <code>NaN</code>
   */
  public static boolean isNaN(float v)
  {
    // This works since NaN != NaN is the only reflexive inequality
    // comparison which returns true.
    return v != v;
  }

  /**
   * Return <code>true</code> if the <code>float</code> has a value
   * equal to either <code>NEGATIVE_INFINITY</code> or
   * <code>POSITIVE_INFINITY</code>, otherwise return <code>false</code>.
   *
   * @param v the <code>float</code> to compare
   * @return whether the argument is (-/+) infinity
   */
  public static boolean isInfinite(float v)
  {
    return v == POSITIVE_INFINITY || v == NEGATIVE_INFINITY;
  }

  /**
   * Return <code>true</code> if the value of this <code>Float</code>
   * is the same as <code>NaN</code>, otherwise return <code>false</code>.
   *
   * @return whether this <code>Float</code> is <code>NaN</code>
   */
  public boolean isNaN()
  {
    return isNaN(value);
  }

  /**
   * Return <code>true</code> if the value of this <code>Float</code>
   * is the same as <code>NEGATIVE_INFINITY</code> or
   * <code>POSITIVE_INFINITY</code>, otherwise return <code>false</code>.
   *
   * @return whether this <code>Float</code> is (-/+) infinity
   */
  public boolean isInfinite()
  {
    return isInfinite(value);
  }

  /**
   * Convert the <code>float</code> value of this <code>Float</code>
   * to a <code>String</code>.  This method calls
   * <code>Float.toString(float)</code> to do its dirty work.
   *
   * @return the <code>String</code> representation
   * @see #toString(float)
   */
  public String toString()
  {
    return toString(value);
  }

  /**
   * Return the value of this <code>Float</code> as a <code>byte</code>.
   *
   * @return the byte value
   * @since 1.1
   */
  public byte byteValue()
  {
    return (byte) value;
  }

  /**
   * Return the value of this <code>Float</code> as a <code>short</code>.
   *
   * @return the short value
   * @since 1.1
   */
  public short shortValue()
  {
    return (short) value;
  }

  /**
   * Return the value of this <code>Integer</code> as an <code>int</code>.
   *
   * @return the int value
   */
  public int intValue()
  {
    return (int) value;
  }

  /**
   * Return the value of this <code>Integer</code> as a <code>long</code>.
   *
   * @return the long value
   */
  public long longValue()
  {
    return (long) value;
  }

  /**
   * Return the value of this <code>Float</code>.
   *
   * @return the float value
   */
  public float floatValue()
  {
    return value;
  }

  /**
   * Return the value of this <code>Float</code> as a <code>double</code>
   *
   * @return the double value
   */
  public double doubleValue()
  {
    return value;
  }

  /**
   * Return a hashcode representing this Object. <code>Float</code>'s hash
   * code is calculated by calling <code>floatToIntBits(floatValue())</code>.
   *
   * @return this Object's hash code
   * @see #floatToIntBits(float)
   */
  public int hashCode()
  {
    return floatToIntBits(value);
  }

  /**
   * Returns <code>true</code> if <code>obj</code> is an instance of
   * <code>Float</code> and represents the same float value. Unlike comparing
   * two floats with <code>==</code>, this treats two instances of
   * <code>Float.NaN</code> as equal, but treats <code>0.0</code> and
   * <code>-0.0</code> as unequal.
   *
   * <p>Note that <code>f1.equals(f2)</code> is identical to
   * <code>floatToIntBits(f1.floatValue()) ==
   *    floatToIntBits(f2.floatValue())</code>.
   *
   * @param obj the object to compare
   * @return whether the objects are semantically equal
   */
  public boolean equals(Object obj)
  {
    if (! (obj instanceof Float))
      return false;

    float f = ((Float) obj).value;

    // Avoid call to native method. However, some implementations, like gcj,
    // are better off using floatToIntBits(value) == floatToIntBits(f).
    // Check common case first, then check NaN and 0.
    if (value == f)
      return (value != 0) || (1 / value == 1 / f);
    return isNaN(value) && isNaN(f);
  }

  /**
   * Convert the float to the IEEE 754 floating-point "single format" bit
   * layout. Bit 31 (the most significant) is the sign bit, bits 30-23
   * (masked by 0x7f800000) represent the exponent, and bits 22-0
   * (masked by 0x007fffff) are the mantissa. This function collapses all
   * versions of NaN to 0x7fc00000. The result of this function can be used
   * as the argument to <code>Float.intBitsToFloat(int)</code> to obtain the
   * original <code>float</code> value.
   *
   * @param value the <code>float</code> to convert
   * @return the bits of the <code>float</code>
   * @see #intBitsToFloat(int)
   */
  public static int floatToIntBits(float value)
  {
    return VMFloat.floatToIntBits(value);
  }

  /**
   * Convert the float to the IEEE 754 floating-point "single format" bit
   * layout. Bit 31 (the most significant) is the sign bit, bits 30-23
   * (masked by 0x7f800000) represent the exponent, and bits 22-0
   * (masked by 0x007fffff) are the mantissa. This function leaves NaN alone,
   * rather than collapsing to a canonical value. The result of this function
   * can be used as the argument to <code>Float.intBitsToFloat(int)</code> to
   * obtain the original <code>float</code> value.
   *
   * @param value the <code>float</code> to convert
   * @return the bits of the <code>float</code>
   * @see #intBitsToFloat(int)
   */
  public static int floatToRawIntBits(float value)
  {
    return VMFloat.floatToRawIntBits(value);
  }

  /**
   * Convert the argument in IEEE 754 floating-point "single format" bit
   * layout to the corresponding float. Bit 31 (the most significant) is the
   * sign bit, bits 30-23 (masked by 0x7f800000) represent the exponent, and
   * bits 22-0 (masked by 0x007fffff) are the mantissa. This function leaves
   * NaN alone, so that you can recover the bit pattern with
   * <code>Float.floatToRawIntBits(float)</code>.
   *
   * @param bits the bits to convert
   * @return the <code>float</code> represented by the bits
   * @see #floatToIntBits(float)
   * @see #floatToRawIntBits(float)
   */
  public static float intBitsToFloat(int bits)
  {
    return VMFloat.intBitsToFloat(bits);
  }

  /**
   * Compare two Floats numerically by comparing their <code>float</code>
   * values. The result is positive if the first is greater, negative if the
   * second is greater, and 0 if the two are equal. However, this special
   * cases NaN and signed zero as follows: NaN is considered greater than
   * all other floats, including <code>POSITIVE_INFINITY</code>, and positive
   * zero is considered greater than negative zero.
   *
   * @param f the Float to compare
   * @return the comparison
   * @since 1.2
   */
  public int compareTo(Float f)
  {
    return compare(value, f.value);
  }

  /**
   * Behaves like <code>new Float(x).compareTo(new Float(y))</code>; in
   * other words this compares two floats, special casing NaN and zero,
   * without the overhead of objects.
   *
   * @param x the first float to compare
   * @param y the second float to compare
   * @return the comparison
   * @since 1.4
   */
  public static int compare(float x, float y)
  {
    if (isNaN(x))
      return isNaN(y) ? 0 : 1;
    if (isNaN(y))
      return -1;
    // recall that 0.0 == -0.0, so we convert to infinities and try again
    if (x == 0 && y == 0)
      return (int) (1 / x - 1 / y);
    if (x == y)
      return 0;

    return x > y ? 1 : -1;
  }
}
