/*
 * Copyright 2011-2023 MicroEJ Corp. All rights reserved.
 * This library is provided in source code for use, modification and test, subject to license terms.
 * Any modification of the source code will break MicroEJ Corp. warranties on the whole library.
 */
package ej.bon;

/**
 * This class provides advanced mathematical functions.
 */
public final class XMath {

	private XMath() {
		throw new RuntimeException();
	}

	/**
	 * The <code>double</code> value that is closer than any other to <i>e</i>, the
	 * base of the natural logarithms.
	 */
	public static final double E = 2.718281828459045d;
	/**
	 * The <code>double</code> value that is closer than any other to <i>pi</i>, the
	 * ratio of the circumference of a circle to its diameter.
	 */
	public static final double PI = 3.141592653589793d;

	/**
	 * Returns the absolute value of a <code>double</code> value. If the argument is
	 * not negative, the argument is returned. If the argument is negative, the
	 * negation of the argument is returned. Special cases:
	 * <ul>
	 * <li>If the argument is positive zero or negative zero, the result is positive
	 * zero.
	 * <li>If the argument is infinite, the result is positive infinity.
	 * <li>If the argument is NaN, the result is NaN.
	 * </ul>
	 * In other words, the result is the same as the value of the expression:
	 * <p>
	 * <code>Double.longBitsToDouble((Double.doubleToLongBits(a)&lt;&lt;1)&gt;&gt;&gt;1)</code>
	 *
	 * @param a
	 *            the argument whose absolute value is to be determined
	 * @return the absolute value of the argument.
	 */
	public static double abs(double a) {
		throw new RuntimeException();
	}

	/**
	 * Returns the absolute value of a <code>float</code> value. If the argument is
	 * not negative, the argument is returned. If the argument is negative, the
	 * negation of the argument is returned. Special cases:
	 * <ul>
	 * <li>If the argument is positive zero or negative zero, the result is positive
	 * zero.
	 * <li>If the argument is infinite, the result is positive infinity.
	 * <li>If the argument is NaN, the result is NaN.
	 * </ul>
	 * In other words, the result is the same as the value of the expression:
	 *
	 * <pre>
	 * Float.intBitsToFloat(0x7fffffff &amp; Float.floatToIntBits(a))
	 * </pre>
	 *
	 * @param a
	 *            the argument whose absolute value is to be determined
	 * @return the absolute value of the argument.
	 */
	public static float abs(float a) {
		throw new RuntimeException();
	}

	/**
	 * Returns the absolute value of an <code>int</code> value. If the argument is
	 * not negative, the argument is returned. If the argument is negative, the
	 * negation of the argument is returned.
	 *
	 * <p>
	 * Note that if the argument is equal to the value of
	 * <code>Integer.MIN_VALUE</code>, the most negative representable
	 * <code>int</code> value, the result is that same value, which is negative.
	 *
	 * @param a
	 *            the argument whose absolute value is to be determined
	 * @return the absolute value of the argument.
	 * @see java.lang.Integer#MIN_VALUE
	 */
	public static int abs(int a) {
		throw new RuntimeException();
	}

	/**
	 * Returns the absolute value of a <code>long</code> value. If the argument is
	 * not negative, the argument is returned. If the argument is negative, the
	 * negation of the argument is returned.
	 *
	 * <p>
	 * Note that if the argument is equal to the value of
	 * <code>Long.MIN_VALUE</code>, the most negative representable
	 * <code>long</code> value, the result is that same value, which is negative.
	 *
	 * @param a
	 *            the argument whose absolute value is to be determined
	 * @return the absolute value of the argument.
	 * @see java.lang.Long#MIN_VALUE
	 */
	public static long abs(long a) {
		throw new RuntimeException();
	}

	/**
	 * Returns the smallest (closest to negative infinity) <code>double</code> value
	 * that is greater than or equal to the argument and is equal to a mathematical
	 * integer. Special cases:
	 * <ul>
	 * <li>If the argument value is already equal to a mathematical integer, then
	 * the result is the same as the argument.
	 * <li>If the argument is NaN or an infinity or positive zero or negative zero,
	 * then the result is the same as the argument.
	 * <li>If the argument value is less than zero but greater than -1.0, then the
	 * result is negative zero.
	 * </ul>
	 * Note that the value of <code>Math.ceil(x)</code> is exactly the value of
	 * <code>-Math.floor(-x)</code>.
	 *
	 *
	 * @param a
	 *            a value.
	 * @return the smallest (closest to negative infinity) floating-point value that
	 *         is greater than or equal to the argument and is equal to a
	 *         mathematical integer.
	 */
	public static double ceil(double a) {
		throw new RuntimeException();
	}

	/**
	 * Returns the trigonometric cosine of an angle. Special cases:
	 * <ul>
	 * <li>If the argument is NaN or an infinity, then the result is NaN.
	 * </ul>
	 *
	 * <p>
	 * The computed result must be within 1 ulp of the exact result. Results must be
	 * semi-monotonic.
	 *
	 * @param a
	 *            an angle, in radians.
	 * @return the cosine of the argument.
	 */
	public static double cos(double a) {
		throw new RuntimeException();
	}

	/**
	 * Returns the largest (closest to positive infinity) <code>double</code> value
	 * that is less than or equal to the argument and is equal to a mathematical
	 * integer. Special cases:
	 * <ul>
	 * <li>If the argument value is already equal to a mathematical integer, then
	 * the result is the same as the argument.
	 * <li>If the argument is NaN or an infinity or positive zero or negative zero,
	 * then the result is the same as the argument.
	 * </ul>
	 *
	 * @param a
	 *            a value.
	 * @return the largest (closest to positive infinity) floating-point value that
	 *         less than or equal to the argument and is equal to a mathematical
	 *         integer.
	 */
	public static double floor(double a) {
		throw new RuntimeException();
	}

	/**
	 * Returns the greater of two <code>double</code> values. That is, the result is
	 * the argument closer to positive infinity. If the arguments have the same
	 * value, the result is that same value. If either value is NaN, then the result
	 * is NaN. Unlike the numerical comparison operators, this method considers
	 * negative zero to be strictly smaller than positive zero. If one argument is
	 * positive zero and the other negative zero, the result is positive zero.
	 *
	 * @param a
	 *            an argument.
	 * @param b
	 *            another argument.
	 * @return the larger of <code>a</code> and <code>b</code>.
	 */
	public static double max(double a, double b) {
		throw new RuntimeException();
	}

	/**
	 * Returns the greater of two <code>float</code> values. That is, the result is
	 * the argument closer to positive infinity. If the arguments have the same
	 * value, the result is that same value. If either value is NaN, then the result
	 * is NaN. Unlike the numerical comparison operators, this method considers
	 * negative zero to be strictly smaller than positive zero. If one argument is
	 * positive zero and the other negative zero, the result is positive zero.
	 *
	 * @param a
	 *            an argument.
	 * @param b
	 *            another argument.
	 * @return the larger of <code>a</code> and <code>b</code>.
	 */
	public static float max(float a, float b) {
		throw new RuntimeException();
	}

	/**
	 * Returns the greater of two <code>long</code> values. That is, the result is
	 * the argument closer to the value of <code>Long.MAX_VALUE</code>. If the
	 * arguments have the same value, the result is that same value.
	 *
	 * @param a
	 *            an argument.
	 * @param b
	 *            another argument.
	 * @return the larger of <code>a</code> and <code>b</code>.
	 * @see java.lang.Long#MAX_VALUE
	 */
	public static long max(long a, long b) {
		throw new RuntimeException();
	}

	/**
	 * Returns the greater of two <code>int</code> values. That is, the result is
	 * the argument closer to the value of <code>Integer.MAX_VALUE</code>. If the
	 * arguments have the same value, the result is that same value.
	 *
	 * @param a
	 *            an argument.
	 * @param b
	 *            another argument.
	 * @return the larger of <code>a</code> and <code>b</code>.
	 * @see java.lang.Long#MAX_VALUE
	 */
	public static int max(int a, int b) {
		throw new RuntimeException();
	}

	/**
	 * Returns the smaller of two <code>double</code> values. That is, the result is
	 * the value closer to negative infinity. If the arguments have the same value,
	 * the result is that same value. If either value is NaN, then the result is
	 * NaN. Unlike the numerical comparison operators, this method considers
	 * negative zero to be strictly smaller than positive zero. If one argument is
	 * positive zero and the other is negative zero, the result is negative zero.
	 *
	 * @param a
	 *            an argument.
	 * @param b
	 *            another argument.
	 * @return the smaller of <code>a</code> and <code>b</code>.
	 */
	public static double min(double a, double b) {
		throw new RuntimeException();
	}

	/**
	 * Returns the smaller of two <code>float</code> values. That is, the result is
	 * the value closer to negative infinity. If the arguments have the same value,
	 * the result is that same value. If either value is NaN, then the result is
	 * NaN. Unlike the numerical comparison operators, this method considers
	 * negative zero to be strictly smaller than positive zero. If one argument is
	 * positive zero and the other is negative zero, the result is negative zero.
	 *
	 * @param a
	 *            an argument.
	 * @param b
	 *            another argument.
	 * @return the smaller of <code>a</code> and <code>b.</code>
	 */
	public static float min(float a, float b) {
		throw new RuntimeException();
	}

	/**
	 * Returns the smaller of two <code>int</code> values. That is, the result the
	 * argument closer to the value of <code>Integer.MIN_VALUE</code>. If the
	 * arguments have the same value, the result is that same value.
	 *
	 * @param a
	 *            an argument.
	 * @param b
	 *            another argument.
	 * @return the smaller of <code>a</code> and <code>b</code>.
	 * @see java.lang.Long#MIN_VALUE
	 */
	public static int min(int a, int b) {
		throw new RuntimeException();
	}

	/**
	 * Returns the smaller of two <code>long</code> values. That is, the result is
	 * the argument closer to the value of <code>Long.MIN_VALUE</code>. If the
	 * arguments have the same value, the result is that same value.
	 *
	 * @param a
	 *            an argument.
	 * @param b
	 *            another argument.
	 * @return the smaller of <code>a</code> and <code>b</code>.
	 * @see java.lang.Long#MIN_VALUE
	 */
	public static long min(long a, long b) {
		throw new RuntimeException();
	}

	/**
	 * Returns the trigonometric sine of an angle. Special cases:
	 * <ul>
	 * <li>If the argument is NaN or an infinity, then the result is NaN.
	 * <li>If the argument is zero, then the result is a zero with the same sign as
	 * the argument.
	 * </ul>
	 *
	 * <p>
	 * The computed result must be within 1 ulp of the exact result. Results must be
	 * semi-monotonic.
	 *
	 * @param a
	 *            an angle, in radians.
	 * @return the sine of the argument.
	 */
	public static double sin(double a) {
		throw new RuntimeException();
	}

	/**
	 * Returns the correctly rounded positive square root of a <code>double</code>
	 * value. Special cases:
	 * <ul>
	 * <li>If the argument is NaN or less than zero, then the result is NaN.
	 * <li>If the argument is positive infinity, then the result is positive
	 * infinity.
	 * <li>If the argument is positive zero or negative zero, then the result is the
	 * same as the argument.
	 * </ul>
	 * Otherwise, the result is the <code>double</code> value closest to the true
	 * mathematical square root of the argument value.
	 *
	 * @param a
	 *            a value.
	 * @return the positive square root of <code>a</code>. If the argument is NaN or
	 *         less than zero, the result is NaN.
	 */
	public static double sqrt(double a) {
		throw new RuntimeException();
	}

	/**
	 * Returns the trigonometric tangent of an angle. Special cases:
	 * <ul>
	 * <li>If the argument is NaN or an infinity, then the result is NaN.
	 * <li>If the argument is zero, then the result is a zero with the same sign as
	 * the argument.
	 * </ul>
	 *
	 * <p>
	 * The computed result must be within 1 ulp of the exact result. Results must be
	 * semi-monotonic.
	 *
	 * @param a
	 *            an angle, in radians.
	 * @return the tangent of the argument.
	 */
	public static double tan(double a) {
		throw new RuntimeException();
	}

	/**
	 * Converts an angle measured in radians to an approximately equivalent angle
	 * measured in degrees. The conversion from radians to degrees is generally
	 * inexact; users should <i>not</i> expect <code>cos(toRadians(90.0))</code> to
	 * exactly equal <code>0.0</code>.
	 *
	 * @param angrad
	 *            an angle, in radians
	 * @return the measurement of the angle <code>angrad</code> in degrees.
	 */
	public static double toDegrees(double angrad) {
		throw new RuntimeException();
	}

	/**
	 * Converts an angle measured in degrees to an approximately equivalent angle
	 * measured in radians. The conversion from degrees to radians is generally
	 * inexact.
	 *
	 * @param angdeg
	 *            an angle, in degrees
	 * @return the measurement of the angle <code>angdeg</code> in radians.
	 */
	public static double toRadians(double angdeg) {
		throw new RuntimeException();
	}

	/**
	 * Returns the arc sine of a value; the returned angle is in the range
	 * -<i>pi</i>/2 through <i>pi</i>/2. Special cases:
	 * <ul>
	 * <li>If the argument is NaN or its absolute value is greater than 1, then the
	 * result is NaN.
	 * <li>If the argument is zero, then the result is a zero with the same sign as
	 * the argument.
	 * </ul>
	 *
	 * <p>
	 * The computed result must be within 1 ulp of the exact result. Results must be
	 * semi-monotonic.
	 *
	 * @param a
	 *            the value whose arc sine is to be returned.
	 * @return the arc sine of the argument.
	 */
	public static double asin(double a) {
		throw new RuntimeException();
	}

	/**
	 * Returns the arc cosine of a value; the returned angle is in the range 0.0
	 * through <i>pi</i>. Special case:
	 * <ul>
	 * <li>If the argument is NaN or its absolute value is greater than 1, then the
	 * result is NaN.
	 * </ul>
	 *
	 * <p>
	 * The computed result must be within 1 ulp of the exact result. Results must be
	 * semi-monotonic.
	 *
	 * @param a
	 *            the value whose arc cosine is to be returned.
	 * @return the arc cosine of the argument.
	 */
	public static double acos(double a) {
		throw new RuntimeException();
	}

	/**
	 * Returns the arc tangent of a value; the returned angle is in the range
	 * -<i>pi</i>/2 through <i>pi</i>/2. Special cases:
	 * <ul>
	 * <li>If the argument is NaN, then the result is NaN.
	 * <li>If the argument is zero, then the result is a zero with the same sign as
	 * the argument.
	 * </ul>
	 *
	 * <p>
	 * The computed result must be within 1 ulp of the exact result. Results must be
	 * semi-monotonic.
	 *
	 * @param a
	 *            the value whose arc tangent is to be returned.
	 * @return the arc tangent of the argument.
	 */
	public static double atan(double a) {
		throw new RuntimeException();
	}

	/**
	 * Returns the natural logarithm (base e) of a double value. Special cases:
	 * <ul>
	 * <li>If the argument is NaN or less than zero, then the result is NaN.
	 * <li>If the argument is positive infinity, then the result is positive
	 * infinity.
	 * <li>If the argument is positive zero or negative zero, then the result is
	 * negative infinity.
	 * </ul>
	 * <p>
	 * The computed result must be within 1 ulp of the exact result. Results must be
	 * semi-monotonic.
	 *
	 * @param a
	 *            the value whose the natural logarithm is to be returned
	 * @return the value ln a
	 */
	public static double log(double a) {
		throw new RuntimeException();
	}

	/**
	 * Returns Euler's number e raised to the power of a double value. Special
	 * cases:
	 * <ul>
	 * <li>If the argument is NaN, the result is NaN.
	 * <li>If the argument is positive infinity, then the result is positive
	 * infinity.
	 * <li>If the argument is negative infinity, then the result is positive zero.
	 * </ul>
	 * The computed result must be within 1 ulp of the exact result. Results must be
	 * semi-monotonic.
	 *
	 * @param a
	 *            the exponent to raise e to.
	 * @return the value ea, where e is the base of the natural logarithms.
	 */
	public static double exp(double a) {
		throw new RuntimeException();
	}

	/**
	 * Returns the value of the first argument raised to the power of the second
	 * argument. Special cases:
	 * <ul>
	 * <li>If the second argument is positive or negative zero, then the result is
	 * 1.0.
	 * <li>If the second argument is 1.0, then the result is the same as the first
	 * argument.
	 * <li>If the second argument is NaN, then the result is NaN.
	 * <li>If the first argument is NaN and the second argument is nonzero, then the
	 * result is NaN.
	 *
	 * <li>If
	 * <ul>
	 * <li>the absolute value of the first argument is greater than 1 and the second
	 * argument is positive infinity, or
	 * <li>the absolute value of the first argument is less than 1 and the second
	 * argument is negative infinity,
	 * </ul>
	 * then the result is positive infinity.
	 *
	 * <li>If
	 * <ul>
	 * <li>the absolute value of the first argument is greater than 1 and the second
	 * argument is negative infinity, or
	 * <li>the absolute value of the first argument is less than 1 and the second
	 * argument is positive infinity,
	 * </ul>
	 * then the result is positive zero.
	 *
	 * <li>If the absolute value of the first argument equals 1 and the second
	 * argument is infinite, then the result is NaN.
	 *
	 * <li>If
	 * <ul>
	 * <li>the first argument is positive zero and the second argument is greater
	 * than zero, or
	 * <li>the first argument is positive infinity and the second argument is less
	 * than zero,
	 * </ul>
	 * then the result is positive zero.
	 *
	 * <li>If
	 * <ul>
	 * <li>the first argument is positive zero and the second argument is less than
	 * zero, or
	 * <li>the first argument is positive infinity and the second argument is
	 * greater than zero,
	 * </ul>
	 * then the result is positive infinity.
	 *
	 * <li>If
	 * <ul>
	 * <li>the first argument is negative zero and the second argument is greater
	 * than zero but not a finite odd integer, or
	 * <li>the first argument is negative infinity and the second argument is less
	 * than zero but not a finite odd integer,
	 * </ul>
	 * then the result is positive zero.
	 *
	 * <li>If
	 * <ul>
	 * <li>the first argument is negative zero and the second argument is a positive
	 * finite odd integer, or
	 * <li>the first argument is negative infinity and the second argument is a
	 * negative finite odd integer,
	 * </ul>
	 * then the result is negative zero.
	 *
	 * <li>If
	 * <ul>
	 * <li>the first argument is negative zero and the second argument is less than
	 * zero but not a finite odd integer, or
	 * <li>the first argument is negative infinity and the second argument is
	 * greater than zero but not a finite odd integer,
	 * </ul>
	 * then the result is positive infinity.
	 *
	 * <li>If
	 * <ul>
	 * <li>the first argument is negative zero and the second argument is a negative
	 * finite odd integer, or
	 * <li>the first argument is negative infinity and the second argument is a
	 * positive finite odd integer,
	 * </ul>
	 * then the result is negative infinity.
	 *
	 * <li>If the first argument is finite and less than zero
	 * <ul>
	 * <li>if the second argument is a finite even integer, the result is equal to
	 * the result of raising the absolute value of the first argument to the power
	 * of the second argument
	 *
	 * <li>if the second argument is a finite odd integer, 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>if the second argument is finite and not an integer, then the result is
	 * NaN.
	 * </ul>
	 *
	 * <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.
	 * </ul>
	 * <p>
	 * (In the foregoing descriptions, a floating-point value is considered to be an
	 * integer if and only if it is finite and a fixed point of the method
	 * {@link Math#ceil ceil} or, equivalently, a fixed point of the method
	 * {@link Math#floor floor}. 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.)
	 *
	 * The computed result must be within 1 ulp of the exact result. Results must be
	 * semi-monotonic.
	 *
	 * @param a
	 *            the base.
	 * @param b
	 *            the exponent.
	 * @return the value ab.
	 */
	public static double pow(double a, double b) {
		throw new RuntimeException();
	}

	/**
	 * Limits a value between two others:
	 * <ol>
	 * <li>If <code>value</code> is lower than <code>min</code>, returns
	 * <code>min</code>.</li>
	 * <li>If <code>value</code> is greater than <code>max</code>, returns
	 * <code>max</code>.</li>
	 * <li>Otherwise, returns <code>value</code>.</li>
	 * </ol>
	 *
	 * @param value
	 *            the value to limit
	 * @param min
	 *            the lower bound
	 * @param max
	 *            the upper bound
	 * @return the limited value
	 * @throws IllegalArgumentException
	 *             if <code>min</code> is greater than <code>max</code>
	 */
	public static int limit(int value, int min, int max) {
		throw new RuntimeException();
	}

	/**
	 * Limits a value between two others:
	 * <ol>
	 * <li>If <code>value</code> is lower than <code>min</code>, returns
	 * <code>min</code>.</li>
	 * <li>If <code>value</code> is greater than <code>max</code>, returns
	 * <code>max</code>.</li>
	 * <li>Otherwise, returns <code>value</code>.</li>
	 * </ol>
	 *
	 * @param value
	 *            the value to limit
	 * @param min
	 *            the lower bound
	 * @param max
	 *            the upper bound
	 * @return the limited value
	 * @throws IllegalArgumentException
	 *             if <code>min</code> is greater than <code>max</code>
	 */
	public static float limit(float value, float min, float max) {
		throw new RuntimeException();
	}

	/**
	 * Limits a value between two others:
	 * <ol>
	 * <li>If <code>value</code> is lower than <code>min</code>, returns
	 * <code>min</code>.</li>
	 * <li>If <code>value</code> is greater than <code>max</code>, returns
	 * <code>max</code>.</li>
	 * <li>Otherwise, returns <code>value</code>.</li>
	 * </ol>
	 *
	 * @param value
	 *            the value to limit
	 * @param min
	 *            the lower bound
	 * @param max
	 *            the upper bound
	 * @return the limited value
	 * @throws IllegalArgumentException
	 *             if <code>min</code> is greater than <code>max</code>
	 */
	public static long limit(long value, long min, long max) {
		throw new RuntimeException();
	}

	/**
	 * Limits a value between two others:
	 * <ol>
	 * <li>If <code>value</code> is lower than <code>min</code>, returns
	 * <code>min</code>.</li>
	 * <li>If <code>value</code> is greater than <code>max</code>, returns
	 * <code>max</code>.</li>
	 * <li>Otherwise, returns <code>value</code>.</li>
	 * </ol>
	 *
	 * @param value
	 *            the value to limit
	 * @param min
	 *            the lower bound
	 * @param max
	 *            the upper bound
	 * @return the limited value
	 * @throws IllegalArgumentException
	 *             if <code>min</code> is greater than <code>max</code>
	 */
	public static double limit(double value, double min, double max) {
		throw new RuntimeException();
	}

	// not implemented in icetea -> not available in api

	// public static double atan2(double a, double b) {
	// throw new RuntimeException();
	// }
	//
	// public static double cbrt(double a) {
	// throw new RuntimeException();
	// }
	//
	// public static double hypot(double a, double b) {
	// throw new RuntimeException();
	// }
	//
	// public static double log10(double a) {
	// throw new RuntimeException();
	// }
	//
	// public static double cosh(double a) {
	// throw new RuntimeException();
	// }
	//
	// public static double sinh(double a) {
	// throw new RuntimeException();
	// }
	//
	// public static double tanh(double a) {
	// throw new RuntimeException();
	// }

}
