package sizzle.functions;
import java.util.Random;
/**
* The Sizzle implementations of the Sawzall math intrinsics that are not in the
* Java Math class.
*
* The intrinsics that are implemented by the Java Math class are specified in
* {@link SymbolTable}.
*
* @author anthonyu
*
*/
public class SizzleMathIntrinsics {
private static Random random = new Random();
/**
* Return a random floating point number x in the range 0.0 < x < 1.0.
*
* @return A random floating point number x in the range 0.0 < x < 1.0
*/
@FunctionSpec(name = "rand", returnType = "float")
public static double rand() {
return SizzleMathIntrinsics.random.nextDouble();
}
/**
* Return a random integer x in the range 0 <= x < n.
*
* @param a
* A int representing one greater than the maximum value desired
*
* @return A random integer x in the range 0 <= x < n
*
* @throws IllegalArgumentException
* When n < 1
*/
@FunctionSpec(name = "nrand", returnType = "int", formalParameters = { "int" })
public static long nRand(final long n) {
if (n < 1)
throw new IllegalArgumentException("n must be greater than zero");
return SizzleMathIntrinsics.random.nextLong() % n;
}
/**
* Round to the nearest integer not larger in absolute value.
*
* @param a
* A double
*
* @return The nearest integer to <em>a</em> not larger in absolute value
*/
@FunctionSpec(name = "trunc", returnType = "float", formalParameters = { "float" })
public static double trunc(final double a) {
if (a == 0.0 || Double.isNaN(a) || Double.isInfinite(a))
return a;
if (a < 0.0)
return Math.ceil(a);
if (a > 0.0)
return Math.floor(a);
throw new IllegalArgumentException("this should be unreachable");
}
/**
* The hyperbolic arc sine function.
*
* @param d
* A double
*
* @return The hyperbolic arc sine of <em>d</em>
*/
@FunctionSpec(name = "asinh", returnType = "float", formalParameters = { "float" })
public static double asinh(final double d) {
return Math.log(d + Math.sqrt(1.0 + d * d));
}
/**
* The hyperbolic arc cosine function.
*
* @param d
* A double
*
* @return The hyperbolic arc cosine of <em>d</em>
*/
@FunctionSpec(name = "acosh", returnType = "float", formalParameters = { "float" })
public static double acosh(final double d) {
return Math.log(d + (d + 1.0) * Math.sqrt((d - 1.0) / (d + 1.0)));
}
/**
* The hyperbolic arc tangent function.
*
* @param d
* A double
*
* @return The hyperbolic arc tangent of <em>d</em>
*/
@FunctionSpec(name = "atanh", returnType = "float", formalParameters = { "float" })
public static double atanh(final double d) {
return Math.log((1.0 + d) * Math.sqrt(1.0 / (1.0 - d * d)));
}
/**
* Tests if a double value is NaN.
*
* @param v
* A double
*
* @return True if <em>v</em> is NaN, false otherwise
*/
@FunctionSpec(name = "isnan", returnType = "bool", formalParameters = { "float" })
public static boolean isNaN(final double v) {
return Double.isNaN(v);
}
/**
* Tests if a double value is infinite.
*
* @param v
* A double
*
* @return True if <em>v</em> is infinite, false otherwise
*/
@FunctionSpec(name = "isinf", returnType = "bool", formalParameters = { "float" })
public static boolean isInfinite(final double v) {
return Double.isInfinite(v);
}
/**
* Tests if a double value is not infinite or NaN.
*
* @param v
* A double
*
* @return True if <em>v</em> is neither infinite nor NaN, false otherwise
*/
@FunctionSpec(name = "isfinite", returnType = "bool", formalParameters = { "float" })
public static boolean isFinite(final double v) {
return !SizzleMathIntrinsics.isNaN(v) && !SizzleMathIntrinsics.isInfinite(v);
}
/**
* Tests if a float value is neither zero, subnormal, infinite, nor NaN.
*
* @param v
* A double
*
* @return True if <em>v</em> is neither zero, subnormal, infinite, nor NaN;
* false otherwise
*/
@FunctionSpec(name = "isnormal", returnType = "bool", formalParameters = { "float" })
public static boolean isNormal(final double v) {
return v != 0.0 && v > 0x0.fffffffffffffp-1022 && !SizzleMathIntrinsics.isNaN(v) && !SizzleMathIntrinsics.isInfinite(v);
}
}