/* java.lang.Math -- common mathematical functions, native allowed
   Copyright (C) 1998, 2001, 2002, 2003, 2006 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;

import gnu.classpath.Configuration;

import java.util.Random;

/**
 * Helper class containing useful mathematical functions and constants.
 * <P>
 *
 * Note that angles are specified in radians.  Conversion functions are
 * provided for your convenience.
 *
 * @author Paul Fisher
 * @author John Keiser
 * @author Eric Blake (ebb9@email.byu.edu)
 * @since 1.0
 */
public final class Math
{
  /**
   * Math is non-instantiable
   */
  private Math()
  {
  }

  static
  {
    if (Configuration.INIT_LOAD_LIBRARY)
      {
	System.loadLibrary("javalang");
      }
  }

  /**
   * A random number generator, initialized on first use.
   */
  private static Random rand;

  /**
   * The most accurate approximation to the mathematical constant <em>e</em>:
   * <code>2.718281828459045</code>. Used in natural log and exp.
   *
   * @see #log(double)
   * @see #exp(double)
   */
  public static final double E = 2.718281828459045;

  /**
   * The most accurate approximation to the mathematical constant <em>pi</em>:
   * <code>3.141592653589793</code>. This is the ratio of a circle's diameter
   * to its circumference.
   */
  public static final double PI = 3.141592653589793;

  /**
   * Take the absolute value of the argument.
   * (Absolute value means make it positive.)
   * <P>
   *
   * Note that the the largest negative value (Integer.MIN_VALUE) cannot
   * be made positive.  In this case, because of the rules of negation in
   * a computer, MIN_VALUE is what will be returned.
   * This is a <em>negative</em> value.  You have been warned.
   *
   * @param i the number to take the absolute value of
   * @return the absolute value
   * @see Integer#MIN_VALUE
   */
  public static int abs(int i)
  {
    return (i < 0) ? -i : i;
  }

  /**
   * Take the absolute value of the argument.
   * (Absolute value means make it positive.)
   * <P>
   *
   * Note that the the largest negative value (Long.MIN_VALUE) cannot
   * be made positive.  In this case, because of the rules of negation in
   * a computer, MIN_VALUE is what will be returned.
   * This is a <em>negative</em> value.  You have been warned.
   *
   * @param l the number to take the absolute value of
   * @return the absolute value
   * @see Long#MIN_VALUE
   */
  public static long abs(long l)
  {
    return (l < 0) ? -l : l;
  }

  /**
   * Take the absolute value of the argument.
   * (Absolute value means make it positive.)
   * <P>
   *
   * This is equivalent, but faster than, calling
   * <code>Float.intBitsToFloat(0x7fffffff & Float.floatToIntBits(a))</code>.
   *
   * @param f the number to take the absolute value of
   * @return the absolute value
   */
  public static float abs(float f)
  {
    return (f <= 0) ? 0 - f : f;
  }

  /**
   * Take the absolute value of the argument.
   * (Absolute value means make it positive.)
   *
   * This is equivalent, but faster than, calling
   * <code>Double.longBitsToDouble(Double.doubleToLongBits(a)
   *       &lt;&lt; 1) &gt;&gt;&gt; 1);</code>.
   *
   * @param d the number to take the absolute value of
   * @return the absolute value
   */
  public static double abs(double d)
  {
    return (d <= 0) ? 0 - d : d;
  }

  /**
   * Return whichever argument is smaller.
   *
   * @param a the first number
   * @param b a second number
   * @return the smaller of the two numbers
   */
  public static int min(int a, int b)
  {
    return (a < b) ? a : b;
  }

  /**
   * Return whichever argument is smaller.
   *
   * @param a the first number
   * @param b a second number
   * @return the smaller of the two numbers
   */
  public static long min(long a, long b)
  {
    return (a < b) ? a : b;
  }

  /**
   * Return whichever argument is smaller. If either argument is NaN, the
   * result is NaN, and when comparing 0 and -0, -0 is always smaller.
   *
   * @param a the first number
   * @param b a second number
   * @return the smaller of the two numbers
   */
  public static float min(float a, float b)
  {
    // this check for NaN, from JLS 15.21.1, saves a method call
    if (a != a)
      return a;
    // no need to check if b is NaN; < will work correctly
    // recall that -0.0 == 0.0, but [+-]0.0 - [+-]0.0 behaves special
    if (a == 0 && b == 0)
      return -(-a - b);
    return (a < b) ? a : b;
  }

  /**
   * Return whichever argument is smaller. If either argument is NaN, the
   * result is NaN, and when comparing 0 and -0, -0 is always smaller.
   *
   * @param a the first number
   * @param b a second number
   * @return the smaller of the two numbers
   */
  public static double min(double a, double b)
  {
    // this check for NaN, from JLS 15.21.1, saves a method call
    if (a != a)
      return a;
    // no need to check if b is NaN; < will work correctly
    // recall that -0.0 == 0.0, but [+-]0.0 - [+-]0.0 behaves special
    if (a == 0 && b == 0)
      return -(-a - b);
    return (a < b) ? a : b;
  }

  /**
   * Return whichever argument is larger.
   *
   * @param a the first number
   * @param b a second number
   * @return the larger of the two numbers
   */
  public static int max(int a, int b)
  {
    return (a > b) ? a : b;
  }

  /**
   * Return whichever argument is larger.
   *
   * @param a the first number
   * @param b a second number
   * @return the larger of the two numbers
   */
  public static long max(long a, long b)
  {
    return (a > b) ? a : b;
  }

  /**
   * Return whichever argument is larger. If either argument is NaN, the
   * result is NaN, and when comparing 0 and -0, 0 is always larger.
   *
   * @param a the first number
   * @param b a second number
   * @return the larger of the two numbers
   */
  public static float max(float a, float b)
  {
    // this check for NaN, from JLS 15.21.1, saves a method call
    if (a != a)
      return a;
    // no need to check if b is NaN; > will work correctly
    // recall that -0.0 == 0.0, but [+-]0.0 - [+-]0.0 behaves special
    if (a == 0 && b == 0)
      return a - -b;
    return (a > b) ? a : b;
  }

  /**
   * Return whichever argument is larger. If either argument is NaN, the
   * result is NaN, and when comparing 0 and -0, 0 is always larger.
   *
   * @param a the first number
   * @param b a second number
   * @return the larger of the two numbers
   */
  public static double max(double a, double b)
  {
    // this check for NaN, from JLS 15.21.1, saves a method call
    if (a != a)
      return a;
    // no need to check if b is NaN; > will work correctly
    // recall that -0.0 == 0.0, but [+-]0.0 - [+-]0.0 behaves special
    if (a == 0 && b == 0)
      return a - -b;
    return (a > b) ? a : b;
  }

  /**
   * The trigonometric function <em>sin</em>. The sine of NaN or infinity is
   * NaN, and the sine of 0 retains its sign. This is accurate within 1 ulp,
   * and is semi-monotonic.
   *
   * @param a the angle (in radians)
   * @return sin(a)
   */
  public static native double sin(double a);

  /**
   * The trigonometric function <em>cos</em>. The cosine of NaN or infinity is
   * NaN. This is accurate within 1 ulp, and is semi-monotonic.
   *
   * @param a the angle (in radians)
   * @return cos(a)
   */
  public static native double cos(double a);

  /**
   * The trigonometric function <em>tan</em>. The tangent of NaN or infinity
   * is NaN, and the tangent of 0 retains its sign. This is accurate within 1
   * ulp, and is semi-monotonic.
   *
   * @param a the angle (in radians)
   * @return tan(a)
   */
  public static native double tan(double a);

  /**
   * The trigonometric function <em>arcsin</em>. The range of angles returned
   * is -pi/2 to pi/2 radians (-90 to 90 degrees). If the argument is NaN or
   * its absolute value is beyond 1, the result is NaN; and the arcsine of
   * 0 retains its sign. This is accurate within 1 ulp, and is semi-monotonic.
   *
   * @param a the sin to turn back into an angle
   * @return arcsin(a)
   */
  public static native double asin(double a);

  /**
   * The trigonometric function <em>arccos</em>. The range of angles returned
   * is 0 to pi radians (0 to 180 degrees). If the argument is NaN or
   * its absolute value is beyond 1, the result is NaN. This is accurate
   * within 1 ulp, and is semi-monotonic.
   *
   * @param a the cos to turn back into an angle
   * @return arccos(a)
   */
  public static native double acos(double a);

  /**
   * The trigonometric function <em>arcsin</em>. The range of angles returned
   * is -pi/2 to pi/2 radians (-90 to 90 degrees). If the argument is NaN, the
   * result is NaN; and the arctangent of 0 retains its sign. This is accurate
   * within 1 ulp, and is semi-monotonic.
   *
   * @param a the tan to turn back into an angle
   * @return arcsin(a)
   * @see #atan2(double, double)
   */
  public static native double atan(double a);

  /**
   * A special version of the trigonometric function <em>arctan</em>, for
   * converting rectangular coordinates <em>(x, y)</em> to polar
   * <em>(r, theta)</em>. This computes the arctangent of x/y in the range
   * of -pi to pi radians (-180 to 180 degrees). Special cases:<ul>
   * <li>If either argument is NaN, the result is NaN.</li>
   * <li>If the first argument is positive zero and the second argument is
   * positive, or the first argument is positive and finite and the second
   * argument is positive infinity, then the result is positive zero.</li>
   * <li>If the first argument is negative zero and the second argument is
   * positive, or the first argument is negative and finite and the second
   * argument is positive infinity, then the result is negative zero.</li>
   * <li>If the first argument is positive zero and the second argument is
   * negative, or the first argument is positive and finite and the second
   * argument is negative infinity, then the result is the double value
   * closest to pi.</li>
   * <li>If the first argument is negative zero and the second argument is
   * negative, or the first argument is negative and finite and the second
   * argument is negative infinity, then the result is the double value
   * closest to -pi.</li>
   * <li>If the first argument is positive and the second argument is
   * positive zero or negative zero, or the first argument is positive
   * infinity and the second argument is finite, then the result is the
   * double value closest to pi/2.</li>
   * <li>If the first argument is negative and the second argument is
   * positive zero or negative zero, or the first argument is negative
   * infinity and the second argument is finite, then the result is the
   * double value closest to -pi/2.</li>
   * <li>If both arguments are positive infinity, then the result is the
   * double value closest to pi/4.</li>
   * <li>If the first argument is positive infinity and the second argument
   * is negative infinity, then the result is the double value closest to
   * 3*pi/4.</li>
   * <li>If the first argument is negative infinity and the second argument
   * is positive infinity, then the result is the double value closest to
   * -pi/4.</li>
   * <li>If both arguments are negative infinity, then the result is the
   * double value closest to -3*pi/4.</li>
   *
   * </ul><p>This is accurate within 2 ulps, and is semi-monotonic. To get r,
   * use sqrt(x*x+y*y).
   *
   * @param y the y position
   * @param x the x position
   * @return <em>theta</em> in the conversion of (x, y) to (r, theta)
   * @see #atan(double)
   */
  public static native double atan2(double y, double x);

  /**
   * Take <em>e</em><sup>a</sup>.  The opposite of <code>log()</code>. If the
   * argument is NaN, the result is NaN; if the argument is positive infinity,
   * the result is positive infinity; and if the argument is negative
   * infinity, the result is positive zero. This is accurate within 1 ulp,
   * and is semi-monotonic.
   *
   * @param a the number to raise to the power
   * @return the number raised to the power of <em>e</em>
   * @see #log(double)
   * @see #pow(double, double)
   */
  public static native double exp(double a);

  /**
   * Take ln(a) (the natural log).  The opposite of <code>exp()</code>. If the
   * argument is NaN or negative, the result is NaN; if the argument is
   * positive infinity, the result is positive infinity; and if the argument
   * is either zero, the result is negative infinity. This is accurate within
   * 1 ulp, and is semi-monotonic.
   *
   * <p>Note that the way to get log<sub>b</sub>(a) is to do this:
   * <code>ln(a) / ln(b)</code>.
   *
   * @param a the number to take the natural log of
   * @return the natural log of <code>a</code>
   * @see #exp(double)
   */
  public static native double log(double a);

  /**
   * Take a square root. If the argument is NaN or negative, the result is
   * NaN; if the argument is positive infinity, the result is positive
   * infinity; and if the result is either zero, the result is the same.
   * This is accurate within the limits of doubles.
   *
   * <p>For other roots, use pow(a, 1 / rootNumber).
   *
   * @param a the numeric argument
   * @return the square root of the argument
   * @see #pow(double, double)
   */
  public static native double sqrt(double a);

  /**
   * Raise a number to a power. Special cases:<ul>
   * <li>If the second argument is positive or negative zero, then the result
   * is 1.0.</li>
   * <li>If the second argument is 1.0, then the result is the same as the
   * first argument.</li>
   * <li>If the second argument is NaN, then the result is NaN.</li>
   * <li>If the first argument is NaN and the second argument is nonzero,
   * then the result is NaN.</li>
   * <li>If the absolute value of the first argument is greater than 1 and
   * the second argument is positive infinity, or the absolute value of the
   * first argument is less than 1 and the second argument is negative
   * infinity, then the result is positive infinity.</li>
   * <li>If the absolute value of the first argument is greater than 1 and
   * the second argument is negative infinity, or the absolute value of the
   * first argument is less than 1 and the second argument is positive
   * infinity, then the result is positive zero.</li>
   * <li>If the absolute value of the first argument equals 1 and the second
   * argument is infinite, then the result is NaN.</li>
   * <li>If the first argument is positive zero and the second argument is
   * greater than zero, or the first argument is positive infinity and the
   * second argument is less than zero, then the result is positive zero.</li>
   * <li>If the first argument is positive zero and the second argument is
   * less than zero, or the first argument is positive infinity and the
   * second argument is greater than zero, then the result is positive
   * infinity.</li>
   * <li>If the first argument is negative zero and the second argument is
   * greater than zero but not a finite odd integer, or the first argument is
   * negative infinity and the second argument is less than zero but not a
   * finite odd integer, then the result is positive zero.</li>
   * <li>If the first argument is negative zero and the second argument is a
   * positive finite odd integer, or the first argument is negative infinity
   * and the second argument is a negative finite odd integer, then the result
   * is negative zero.</li>
   * <li>If the first argument is negative zero and the second argument is
   * less than zero but not a finite odd integer, or the first argument is
   * negative infinity and the second argument is greater than zero but not a
   * finite odd integer, then the result is positive infinity.</li>
   * <li>If the first argument is negative zero and the second argument is a
   * negative finite odd integer, or the first argument is negative infinity
   * and the second argument is a positive finite odd integer, then the result
   * is negative infinity.</li>
   * <li>If the first argument is less than zero and the second argument is a
   * finite even integer, then the result is equal to the result of raising
   * the absolute value of the first argument to the power of the second
   * argument.</li>
   * <li>If the first argument is less than zero and the second argument is a
   * finite odd integer, then the result is equal to the negative of the
   * result of raising the absolute value of the first argument to the power
   * of the second argument.</li>
   * <li>If the first argument is finite and less than zero and the second
   * argument is finite and not an integer, then the result is NaN.</li>
   * <li>If both arguments are integers, then the result is exactly equal to
   * the mathematical result of raising the first argument to the power of
   * the second argument if that result can in fact be represented exactly as
   * a double value.</li>
   *
   * </ul><p>(In the foregoing descriptions, a floating-point value is
   * considered to be an integer if and only if it is a fixed point of the
   * method {@link #ceil(double)} or, equivalently, a fixed point of the
   * method {@link #floor(double)}. A value is a fixed point of a one-argument
   * method if and only if the result of applying the method to the value is
   * equal to the value.) This is accurate within 1 ulp, and is semi-monotonic.
   *
   * @param a the number to raise
   * @param b the power to raise it to
   * @return a<sup>b</sup>
   */
  public static native double pow(double a, double b);

  /**
   * Get the IEEE 754 floating point remainder on two numbers. This is the
   * value of <code>x - y * <em>n</em></code>, where <em>n</em> is the closest
   * double to <code>x / y</code> (ties go to the even n); for a zero
   * remainder, the sign is that of <code>x</code>. If either argument is NaN,
   * the first argument is infinite, or the second argument is zero, the result
   * is NaN; if x is finite but y is infinite, the result is x. This is
   * accurate within the limits of doubles.
   *
   * @param x the dividend (the top half)
   * @param y the divisor (the bottom half)
   * @return the IEEE 754-defined floating point remainder of x/y
   * @see #rint(double)
   */
  public static native double IEEEremainder(double x, double y);

  /**
   * Take the nearest integer that is that is greater than or equal to the
   * argument. If the argument is NaN, infinite, or zero, the result is the
   * same; if the argument is between -1 and 0, the result is negative zero.
   * Note that <code>Math.ceil(x) == -Math.floor(-x)</code>.
   *
   * @param a the value to act upon
   * @return the nearest integer &gt;= <code>a</code>
   */
  public static native double ceil(double a);

  /**
   * Take the nearest integer that is that is less than or equal to the
   * argument. If the argument is NaN, infinite, or zero, the result is the
   * same. Note that <code>Math.ceil(x) == -Math.floor(-x)</code>.
   *
   * @param a the value to act upon
   * @return the nearest integer &lt;= <code>a</code>
   */
  public static native double floor(double a);

  /**
   * Take the nearest integer to the argument.  If it is exactly between
   * two integers, the even integer is taken. If the argument is NaN,
   * infinite, or zero, the result is the same.
   *
   * @param a the value to act upon
   * @return the nearest integer to <code>a</code>
   */
  public static native double rint(double a);

  /**
   * Take the nearest integer to the argument.  This is equivalent to
   * <code>(int) Math.floor(a + 0.5f)</code>. If the argument is NaN, the result
   * is 0; otherwise if the argument is outside the range of int, the result
   * will be Integer.MIN_VALUE or Integer.MAX_VALUE, as appropriate.
   *
   * @param a the argument to round
   * @return the nearest integer to the argument
   * @see Integer#MIN_VALUE
   * @see Integer#MAX_VALUE
   */
  public static int round(float a)
  {
    // this check for NaN, from JLS 15.21.1, saves a method call
    if (a != a)
      return 0;
    return (int) floor(a + 0.5f);
  }

  /**
   * Take the nearest long to the argument.  This is equivalent to
   * <code>(long) Math.floor(a + 0.5)</code>. If the argument is NaN, the
   * result is 0; otherwise if the argument is outside the range of long, the
   * result will be Long.MIN_VALUE or Long.MAX_VALUE, as appropriate.
   *
   * @param a the argument to round
   * @return the nearest long to the argument
   * @see Long#MIN_VALUE
   * @see Long#MAX_VALUE
   */
  public static long round(double a)
  {
    // this check for NaN, from JLS 15.21.1, saves a method call
    if (a != a)
      return 0;
    return (long) floor(a + 0.5d);
  }

  /**
   * Get a random number.  This behaves like Random.nextDouble(), seeded by
   * System.currentTimeMillis() when first called. In other words, the number
   * is from a pseudorandom sequence, and lies in the range [+0.0, 1.0).
   * This random sequence is only used by this method, and is threadsafe,
   * although you may want your own random number generator if it is shared
   * among threads.
   *
   * @return a random number
   * @see Random#nextDouble()
   * @see System#currentTimeMillis()
   */
  public static synchronized double random()
  {
    if (rand == null)
      rand = new Random();
    return rand.nextDouble();
  }

  /**
   * Convert from degrees to radians. The formula for this is
   * radians = degrees * (pi/180); however it is not always exact given the
   * limitations of floating point numbers.
   *
   * @param degrees an angle in degrees
   * @return the angle in radians
   * @since 1.2
   */
  public static double toRadians(double degrees)
  {
    return (degrees * PI) / 180;
  }

  /**
   * Convert from radians to degrees. The formula for this is
   * degrees = radians * (180/pi); however it is not always exact given the
   * limitations of floating point numbers.
   *
   * @param rads an angle in radians
   * @return the angle in degrees
   * @since 1.2
   */
  public static double toDegrees(double rads)
  {
    return (rads * 180) / PI;
  }

  /**
   * <p>
   * Take a cube root. If the argument is <code>NaN</code>, an infinity or
   * zero, then the original value is returned.  The returned result is
   * within 1 ulp of the exact result.  For a finite value, <code>x</code>,
   * the cube root of <code>-x</code> is equal to the negation of the cube root
   * of <code>x</code>. 
   * </p>
   * <p>
   * For a square root, use <code>sqrt</code>.  For other roots, use
   * <code>pow(a, 1 / rootNumber)</code>.
   * </p>
   *
   * @param a the numeric argument
   * @return the cube root of the argument
   * @see #sqrt(double)
   * @see #pow(double, double)
   * @since 1.5
   */
  public static native double cbrt(double a);

  /**
   * <p>
   * Returns the hyperbolic cosine of the given value.  For a value,
   * <code>x</code>, the hyperbolic cosine is <code>(e<sup>x</sup> + 
   * e<sup>-x</sup>)/2</code>
   * with <code>e</code> being <a href="#E">Euler's number</a>.  The returned
   * result is within 2.5 ulps of the exact result.
   * </p>
   * <p>
   * If the supplied value is <code>NaN</code>, then the original value is
   * returned.  For either infinity, positive infinity is returned.
   * The hyperbolic cosine of zero is 1.0.
   * </p>
   * 
   * @param a the numeric argument
   * @return the hyperbolic cosine of <code>a</code>.
   * @since 1.5
   */
  public static native double cosh(double a);

  /**
   * <p>
   * Returns <code>e<sup>a</sup> - 1.  For values close to 0, the
   * result of <code>expm1(a) + 1</code> tend to be much closer to the
   * exact result than simply <code>exp(x)</code>.  The result is within
   * 1 ulp of the exact result, and results are semi-monotonic.  For finite
   * inputs, the returned value is greater than or equal to -1.0.  Once
   * a result enters within half a ulp of this limit, the limit is returned.
   * </p>   
   * <p>
   * For <code>NaN</code>, positive infinity and zero, the original value
   * is returned.  Negative infinity returns a result of -1.0 (the limit).
   * </p>
   * 
   * @param a the numeric argument
   * @return <code>e<sup>a</sup> - 1</code>
   * @since 1.5
   */
  public static native double expm1(double a);

  /**
   * <p>
   * Returns the hypotenuse, <code>a<sup>2</sup> + b<sup>2</sup></code>,
   * without intermediate overflow or underflow.  The returned result is
   * within 1 ulp of the exact result.  If one parameter is held constant,
   * then the result in the other parameter is semi-monotonic.
   * </p>
   * <p>
   * If either of the arguments is an infinity, then the returned result
   * is positive infinity.  Otherwise, if either argument is <code>NaN</code>,
   * then <code>NaN</code> is returned.
   * </p>
   * 
   * @param a the first parameter.
   * @param b the second parameter.
   * @return the hypotenuse matching the supplied parameters.
   * @since 1.5
   */
  public static native double hypot(double a, double b);

  /**
   * <p>
   * Returns the base 10 logarithm of the supplied value.  The returned
   * result is within 1 ulp of the exact result, and the results are
   * semi-monotonic.
   * </p>
   * <p>
   * Arguments of either <code>NaN</code> or less than zero return
   * <code>NaN</code>.  An argument of positive infinity returns positive
   * infinity.  Negative infinity is returned if either positive or negative
   * zero is supplied.  Where the argument is the result of
   * <code>10<sup>n</sup</code>, then <code>n</code> is returned.
   * </p>
   *
   * @param a the numeric argument.
   * @return the base 10 logarithm of <code>a</code>.
   * @since 1.5
   */
  public static native double log10(double a);

  /**
   * <p>
   * Returns the natural logarithm resulting from the sum of the argument,
   * <code>a</code> and 1.  For values close to 0, the
   * result of <code>log1p(a)</code> tend to be much closer to the
   * exact result than simply <code>log(1.0+a)</code>.  The returned
   * result is within 1 ulp of the exact result, and the results are
   * semi-monotonic.
   * </p>
   * <p>
   * Arguments of either <code>NaN</code> or less than -1 return
   * <code>NaN</code>.  An argument of positive infinity or zero
   * returns the original argument.  Negative infinity is returned from an
   * argument of -1.
   * </p>
   *
   * @param a the numeric argument.
   * @return the natural logarithm of <code>a</code> + 1.
   * @since 1.5
   */
  public static native double log1p(double a);

  /**
   * <p>
   * Returns the sign of the argument as follows:
   * </p>
   * <ul>
   * <li>If <code>a</code> is greater than zero, the result is 1.0.</li>
   * <li>If <code>a</code> is less than zero, the result is -1.0.</li>
   * <li>If <code>a</code> is <code>NaN</code>, the result is <code>NaN</code>.
   * <li>If <code>a</code> is positive or negative zero, the result is the
   * same.</li>
   * </ul>
   *
   * @param a the numeric argument.
   * @return the sign of the argument.
   * @since 1.5.
   */
  public static double signum(double a)
  {
    if (Double.isNaN(a))
      return Double.NaN;
    if (a > 0)
      return 1.0;
    if (a < 0)
      return -1.0;
    return a;
  }

  /**
   * <p>
   * Returns the sign of the argument as follows:
   * </p>
   * <ul>
   * <li>If <code>a</code> is greater than zero, the result is 1.0f.</li>
   * <li>If <code>a</code> is less than zero, the result is -1.0f.</li>
   * <li>If <code>a</code> is <code>NaN</code>, the result is <code>NaN</code>.
   * <li>If <code>a</code> is positive or negative zero, the result is the
   * same.</li>
   * </ul>
   *
   * @param a the numeric argument.
   * @return the sign of the argument.
   * @since 1.5.
   */
  public static float signum(float a)
  {
    if (Float.isNaN(a))
      return Float.NaN;
    if (a > 0)
      return 1.0f;
    if (a < 0)
      return -1.0f;
    return a;
  }

  /**
   * <p>
   * Returns the hyperbolic sine of the given value.  For a value,
   * <code>x</code>, the hyperbolic sine is <code>(e<sup>x</sup> - 
   * e<sup>-x</sup>)/2</code>
   * with <code>e</code> being <a href="#E">Euler's number</a>.  The returned
   * result is within 2.5 ulps of the exact result.
   * </p>
   * <p>
   * If the supplied value is <code>NaN</code>, an infinity or a zero, then the
   * original value is returned.
   * </p>
   * 
   * @param a the numeric argument
   * @return the hyperbolic sine of <code>a</code>.
   * @since 1.5
   */
  public static native double sinh(double a);

  /**
   * <p>
   * Returns the hyperbolic tangent of the given value.  For a value,
   * <code>x</code>, the hyperbolic tangent is <code>(e<sup>x</sup> - 
   * e<sup>-x</sup>)/(e<sup>x</sup> + e<sup>-x</sup>)</code>
   * (i.e. <code>sinh(a)/cosh(a)</code>)
   * with <code>e</code> being <a href="#E">Euler's number</a>.  The returned
   * result is within 2.5 ulps of the exact result.  The absolute value
   * of the exact result is always less than 1.  Computed results are thus
   * less than or equal to 1 for finite arguments, with results within
   * half a ulp of either positive or negative 1 returning the appropriate
   * limit value (i.e. as if the argument was an infinity).
   * </p>
   * <p>
   * If the supplied value is <code>NaN</code> or zero, then the original
   * value is returned.  Positive infinity returns +1.0 and negative infinity
   * returns -1.0.
   * </p>
   * 
   * @param a the numeric argument
   * @return the hyperbolic tangent of <code>a</code>.
   * @since 1.5
   */
  public static native double tanh(double a);

  /**
   * Return the ulp for the given double argument.  The ulp is the
   * difference between the argument and the next larger double.  Note
   * that the sign of the double argument is ignored, that is,
   * ulp(x) == ulp(-x).  If the argument is a NaN, then NaN is returned.
   * If the argument is an infinity, then +Inf is returned.  If the
   * argument is zero (either positive or negative), then
   * {@link Double#MIN_VALUE} is returned.
   * @param d the double whose ulp should be returned
   * @return the difference between the argument and the next larger double
   * @since 1.5
   */
  public static double ulp(double d)
  {
    if (Double.isNaN(d))
      return d;
    if (Double.isInfinite(d))
      return Double.POSITIVE_INFINITY;
    // This handles both +0.0 and -0.0.
    if (d == 0.0)
      return Double.MIN_VALUE;
    long bits = Double.doubleToLongBits(d);
    final int mantissaBits = 52;
    final int exponentBits = 11;
    final long mantMask = (1L << mantissaBits) - 1;
    long mantissa = bits & mantMask;
    final long expMask = (1L << exponentBits) - 1;
    long exponent = (bits >>> mantissaBits) & expMask;

    // Denormal number, so the answer is easy.
    if (exponent == 0)
      {
        long result = (exponent << mantissaBits) | 1L;
        return Double.longBitsToDouble(result);
      }

    // Conceptually we want to have '1' as the mantissa.  Then we would
    // shift the mantissa over to make a normal number.  If this underflows
    // the exponent, we will make a denormal result.
    long newExponent = exponent - mantissaBits;
    long newMantissa;
    if (newExponent > 0)
      newMantissa = 0;
    else
      {
        newMantissa = 1L << -(newExponent - 1);
        newExponent = 0;
      }
    return Double.longBitsToDouble((newExponent << mantissaBits) | newMantissa);
  }

  /**
   * Return the ulp for the given float argument.  The ulp is the
   * difference between the argument and the next larger float.  Note
   * that the sign of the float argument is ignored, that is,
   * ulp(x) == ulp(-x).  If the argument is a NaN, then NaN is returned.
   * If the argument is an infinity, then +Inf is returned.  If the
   * argument is zero (either positive or negative), then
   * {@link Float#MIN_VALUE} is returned.
   * @param f the float whose ulp should be returned
   * @return the difference between the argument and the next larger float
   * @since 1.5
   */
  public static float ulp(float f)
  {
    if (Float.isNaN(f))
      return f;
    if (Float.isInfinite(f))
      return Float.POSITIVE_INFINITY;
    // This handles both +0.0 and -0.0.
    if (f == 0.0)
      return Float.MIN_VALUE;
    int bits = Float.floatToIntBits(f);
    final int mantissaBits = 23;
    final int exponentBits = 8;
    final int mantMask = (1 << mantissaBits) - 1;
    int mantissa = bits & mantMask;
    final int expMask = (1 << exponentBits) - 1;
    int exponent = (bits >>> mantissaBits) & expMask;

    // Denormal number, so the answer is easy.
    if (exponent == 0)
      {
        int result = (exponent << mantissaBits) | 1;
        return Float.intBitsToFloat(result);
      }

    // Conceptually we want to have '1' as the mantissa.  Then we would
    // shift the mantissa over to make a normal number.  If this underflows
    // the exponent, we will make a denormal result.
    int newExponent = exponent - mantissaBits;
    int newMantissa;
    if (newExponent > 0)
      newMantissa = 0;
    else
      {
        newMantissa = 1 << -(newExponent - 1);
        newExponent = 0;
      }
    return Float.intBitsToFloat((newExponent << mantissaBits) | newMantissa);
  }
}
