static char target_percent_s_newline[4];
static tree do_mpfr_arg1 (tree, tree, int (*)(mpfr_ptr, mpfr_srcptr, mp_rnd_t),
const REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *, bool);
+static tree do_mpfr_arg2 (tree, tree, tree,
+ int (*)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t));
/* Return true if NODE should be considered for inline expansion regardless
of the optimization level. This means whenever a function is invoked with
return 0;
}
+/* Fold a builtin function call to hypot, hypotf, or hypotl. Return
+ NULL_TREE if no simplification can be made. */
+
+static tree
+fold_builtin_hypot (tree fndecl, tree arglist, tree type)
+{
+ tree arg0 = TREE_VALUE (arglist);
+ tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
+ tree res;
+
+ if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
+ return NULL_TREE;
+
+ /* Calculate the result when the argument is a constant. */
+ if ((res = do_mpfr_arg2 (arg0, arg1, type, mpfr_hypot)))
+ return res;
+
+ /* If either argument is zero, hypot is fabs of the other. */
+ if (real_zerop (arg0))
+ return fold_build1 (ABS_EXPR, type, arg1);
+ else if (real_zerop (arg1))
+ return fold_build1 (ABS_EXPR, type, arg0);
+
+ /* hypot(x,x) -> x*sqrt(2). */
+ if (operand_equal_p (arg0, arg1, OEP_PURE_SAME))
+ {
+ REAL_VALUE_TYPE sqrt2;
+
+ real_sqrt (&sqrt2, TYPE_MODE (type), &dconst2);
+ return fold_build2 (MULT_EXPR, type, arg0,
+ build_real (type, sqrt2));
+ }
+
+ /* Transform hypot(-x,y) or hypot(x,-y) or hypot(-x,-y) into
+ hypot(x,y). */
+ if (TREE_CODE (arg0) == NEGATE_EXPR || TREE_CODE (arg1) == NEGATE_EXPR)
+ {
+ tree narg0 = (TREE_CODE (arg0) == NEGATE_EXPR)
+ ? TREE_OPERAND (arg0, 0) : arg0;
+ tree narg1 = (TREE_CODE (arg1) == NEGATE_EXPR)
+ ? TREE_OPERAND (arg1, 0) : arg1;
+ tree narglist = tree_cons (NULL_TREE, narg0,
+ build_tree_list (NULL_TREE, narg1));
+ return build_function_call_expr (fndecl, narglist);
+ }
+
+ return NULL_TREE;
+}
+
+
/* Fold a builtin function call to pow, powf, or powl. Return
NULL_TREE if no simplification can be made. */
static tree
{
tree arg0 = TREE_VALUE (arglist);
tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
+ tree res;
if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
return NULL_TREE;
+ /* Calculate the result when the argument is a constant. */
+ if ((res = do_mpfr_arg2 (arg0, arg1, type, mpfr_pow)))
+ return res;
+
/* Optimize pow(1.0,y) = 1.0. */
if (real_onep (arg0))
return omit_one_operand (type, build_real (type, dconst1), arg1);
&dconstm1, NULL, false);
break;
+ CASE_FLT_FN (BUILT_IN_ATAN2):
+ if (validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
+ return do_mpfr_arg2 (TREE_VALUE (arglist),
+ TREE_VALUE (TREE_CHAIN (arglist)),
+ type, mpfr_atan2);
+ break;
+
+ CASE_FLT_FN (BUILT_IN_HYPOT):
+ return fold_builtin_hypot (fndecl, arglist, type);
+
CASE_FLT_FN (BUILT_IN_POW):
return fold_builtin_pow (fndecl, arglist, type);
return true;
}
+/* Helper function for do_mpfr_arg*(). Ensure M is a normal number
+ and no overflow/underflow occurred. INEXACT is true if M was not
+ exacly calculated. TYPE is the tree type for the result. This
+ function assumes that you cleared the MPFR flags and then
+ calculated M to see if anything subsequently set a flag prior to
+ entering this function. Return NULL_TREE if any checks fail. */
+
+static tree
+do_mpfr_ckconv(mpfr_srcptr m, tree type, int inexact)
+{
+ /* Proceed iff we get a normal number, i.e. not NaN or Inf and no
+ overflow/underflow occurred. If -frounding-math, proceed iff the
+ result of calling FUNC was exact. */
+ if (mpfr_number_p (m) && !mpfr_overflow_p() && !mpfr_underflow_p()
+ && (!flag_rounding_math || !inexact))
+ {
+ REAL_VALUE_TYPE rr;
+
+ real_from_mpfr (&rr, m);
+ /* Proceed iff GCC's REAL_VALUE_TYPE can hold the MPFR value,
+ check for overflow/underflow. If the REAL_VALUE_TYPE is zero
+ but the mpft_t is not, then we underflowed in the
+ conversion. */
+ if (!real_isnan (&rr) && !real_isinf (&rr)
+ && (rr.cl == rvc_zero) == (mpfr_zero_p (m) != 0))
+ {
+ REAL_VALUE_TYPE rmode;
+
+ real_convert (&rmode, TYPE_MODE (type), &rr);
+ /* Proceed iff the specified mode can hold the value. */
+ if (real_identical (&rmode, &rr))
+ return build_real (type, rmode);
+ }
+ }
+ return NULL_TREE;
+}
+
/* If argument ARG is a REAL_CST, call the one-argument mpfr function
FUNC on it and return the resulting value as a tree with type TYPE.
If MIN and/or MAX are not NULL, then the supplied ARG must be
if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
{
- REAL_VALUE_TYPE r = TREE_REAL_CST (arg);
+ const REAL_VALUE_TYPE *const ra = &TREE_REAL_CST (arg);
- if (!real_isnan (&r) && !real_isinf (&r)
- && (!min || real_compare (inclusive ? GE_EXPR: GT_EXPR , &r, min))
- && (!max || real_compare (inclusive ? LE_EXPR: LT_EXPR , &r, max)))
+ if (!real_isnan (ra) && !real_isinf (ra)
+ && (!min || real_compare (inclusive ? GE_EXPR: GT_EXPR , ra, min))
+ && (!max || real_compare (inclusive ? LE_EXPR: LT_EXPR , ra, max)))
{
- const enum machine_mode mode = TYPE_MODE (type);
- const int prec = REAL_MODE_FORMAT (mode)->p;
+ const int prec = REAL_MODE_FORMAT (TYPE_MODE (type))->p;
int inexact;
mpfr_t m;
mpfr_init2 (m, prec);
- mpfr_from_real (m, &r);
+ mpfr_from_real (m, ra);
mpfr_clear_flags();
inexact = func (m, m, GMP_RNDN);
-
- /* Proceed iff we get a normal number, i.e. not NaN or Inf
- and no overflow/underflow occurred. If -frounding-math,
- proceed iff the result of calling FUNC was exact. */
- if (mpfr_number_p (m) && !mpfr_overflow_p() && !mpfr_underflow_p()
- && (!flag_rounding_math || !inexact))
- {
- real_from_mpfr (&r, m);
- /* Proceed iff GCC's REAL_VALUE_TYPE can hold the MPFR
- value, check for overflow/underflow. If the
- REAL_VALUE_TYPE is zero but the mpft_t is not, then
- we underflowed in the conversion. */
- if (!real_isnan (&r) && !real_isinf (&r)
- && (r.cl == rvc_zero) == (mpfr_zero_p (m) != 0))
- {
- REAL_VALUE_TYPE rmode;
- real_convert (&rmode, mode, &r);
- /* Proceed iff the specified mode can hold the value. */
- if (real_identical (&rmode, &r))
- result = build_real (type, rmode);
- }
- }
+ result = do_mpfr_ckconv (m, type, inexact);
mpfr_clear (m);
}
}
return result;
}
+
+/* If argument ARG is a REAL_CST, call the two-argument mpfr function
+ FUNC on it and return the resulting value as a tree with type TYPE.
+ The mpfr precision is set to the precision of TYPE. We assume that
+ function FUNC returns zero if the result could be calculated
+ exactly within the requested precision. */
+
+static tree
+do_mpfr_arg2 (tree arg1, tree arg2, tree type,
+ int (*func)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t))
+{
+ tree result = NULL_TREE;
+
+ STRIP_NOPS (arg1);
+ STRIP_NOPS (arg2);
+
+ if (TREE_CODE (arg1) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg1)
+ && TREE_CODE (arg2) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg2))
+ {
+ const REAL_VALUE_TYPE *const ra1 = &TREE_REAL_CST (arg1);
+ const REAL_VALUE_TYPE *const ra2 = &TREE_REAL_CST (arg2);
+
+ if (!real_isnan (ra1) && !real_isinf (ra1)
+ && !real_isnan (ra2) && !real_isinf (ra2))
+ {
+ const int prec = REAL_MODE_FORMAT (TYPE_MODE (type))->p;
+ int inexact;
+ mpfr_t m1, m2;
+
+ mpfr_inits2 (prec, m1, m2, NULL);
+ mpfr_from_real (m1, ra1);
+ mpfr_from_real (m2, ra2);
+ mpfr_clear_flags();
+ inexact = func (m1, m1, m2, GMP_RNDN);
+ result = do_mpfr_ckconv (m1, type, inexact);
+ mpfr_clears (m1, m2, NULL);
+ }
+ }
+
+ return result;
+}
link_error(__LINE__); \
} while (0);
-/* Test that (LOW) < FUNC(ARG) < (HI). */
-#define TESTIT2(FUNC,ARG,LOW,HI) do { \
+/* Range test, check that (LOW) < FUNC(ARG) < (HI). */
+#define TESTIT_R(FUNC,ARG,LOW,HI) do { \
if (__builtin_##FUNC##f(ARG) <= (LOW) || __builtin_##FUNC##f(ARG) >= (HI)) \
link_error(__LINE__); \
if (__builtin_##FUNC(ARG) <= (LOW) || __builtin_##FUNC(ARG) >= (HI)) \
link_error(__LINE__); \
} while (0);
+/* Test that FUNC(ARG1, ARG2) == (RES). */
+#define TESTIT2(FUNC,ARG1,ARG2,RES) do { \
+ if (__builtin_##FUNC##f(ARG1##F, ARG2##F) != RES##F) \
+ link_error(__LINE__); \
+ if (__builtin_##FUNC(ARG1, ARG2) != RES) \
+ link_error(__LINE__); \
+ if (__builtin_##FUNC##l(ARG1##L, ARG2##L) != RES##L) \
+ link_error(__LINE__); \
+ } while (0);
+
+/* Range test, check that (LOW) < FUNC(ARG1,ARG2) < (HI). */
+#define TESTIT2_R(FUNC,ARG1,ARG2,LOW,HI) do { \
+ if (__builtin_##FUNC##f(ARG1, ARG2) <= (LOW) \
+ || __builtin_##FUNC##f(ARG1, ARG2) >= (HI)) \
+ link_error(__LINE__); \
+ if (__builtin_##FUNC(ARG1, ARG2) <= (LOW) \
+ || __builtin_##FUNC(ARG1, ARG2) >= (HI)) \
+ link_error(__LINE__); \
+ if (__builtin_##FUNC##l(ARG1, ARG2) <= (LOW) \
+ || __builtin_##FUNC##l(ARG1, ARG2) >= (HI)) \
+ link_error(__LINE__); \
+ } while (0);
+
int main (void)
{
- TESTIT2 (asin, -1.0, -3.15/2.0, -3.14/2.0); /* asin(-1) == -pi/2 */
+ TESTIT_R (asin, -1.0, -3.15/2.0, -3.14/2.0); /* asin(-1) == -pi/2 */
TESTIT (asin, 0.0, 0.0); /* asin(0) == 0 */
TESTIT (asin, -0.0, -0.0); /* asin(-0) == -0 */
- TESTIT2 (asin, 1.0, 3.14/2.0, 3.15/2.0); /* asin(1) == pi/2 */
+ TESTIT_R (asin, 1.0, 3.14/2.0, 3.15/2.0); /* asin(1) == pi/2 */
- TESTIT2 (acos, -1.0, 3.14, 3.15); /* acos(-1) == pi */
- TESTIT2 (acos, 0.0, 3.14/2.0, 3.15/2.0); /* acos(0) == pi/2 */
- TESTIT2 (acos, -0.0, 3.14/2.0, 3.15/2.0); /* acos(-0) == pi/2 */
+ TESTIT_R (acos, -1.0, 3.14, 3.15); /* acos(-1) == pi */
+ TESTIT_R (acos, 0.0, 3.14/2.0, 3.15/2.0); /* acos(0) == pi/2 */
+ TESTIT_R (acos, -0.0, 3.14/2.0, 3.15/2.0); /* acos(-0) == pi/2 */
TESTIT (acos, 1.0, 0.0); /* acos(1) == 0 */
- TESTIT2 (atan, -1.0, -3.15/4.0, -3.14/4.0); /* atan(-1) == -pi/4 */
+ TESTIT_R (atan, -1.0, -3.15/4.0, -3.14/4.0); /* atan(-1) == -pi/4 */
TESTIT (atan, 0.0, 0.0); /* atan(0) == 0 */
TESTIT (atan, -0.0, -0.0); /* atan(-0) == -0 */
- TESTIT2 (atan, 1.0, 3.14/4.0, 3.15/4.0); /* atan(1) == pi/4 */
+ TESTIT_R (atan, 1.0, 3.14/4.0, 3.15/4.0); /* atan(1) == pi/4 */
- TESTIT2 (asinh, -1.0, -0.89, -0.88); /* asinh(-1) == -0.881... */
+ TESTIT_R (asinh, -1.0, -0.89, -0.88); /* asinh(-1) == -0.881... */
TESTIT (asinh, 0.0, 0.0); /* asinh(0) == 0 */
TESTIT (asinh, -0.0, -0.0); /* asinh(-0) == -0 */
- TESTIT2 (asinh, 1.0, 0.88, 0.89); /* asinh(1) == 0.881... */
+ TESTIT_R (asinh, 1.0, 0.88, 0.89); /* asinh(1) == 0.881... */
TESTIT (acosh, 1.0, 0.0); /* acosh(1) == 0. */
- TESTIT2 (acosh, 2.0, 1.31, 1.32); /* acosh(2) == 1.316... */
+ TESTIT_R (acosh, 2.0, 1.31, 1.32); /* acosh(2) == 1.316... */
- TESTIT2 (atanh, -0.5, -0.55, -0.54); /* atanh(-0.5) == -0.549... */
+ TESTIT_R (atanh, -0.5, -0.55, -0.54); /* atanh(-0.5) == -0.549... */
TESTIT (atanh, 0.0, 0.0); /* atanh(0) == 0 */
TESTIT (atanh, -0.0, -0.0); /* atanh(-0) == -0 */
- TESTIT2 (atanh, 0.5, 0.54, 0.55); /* atanh(0.5) == 0.549... */
+ TESTIT_R (atanh, 0.5, 0.54, 0.55); /* atanh(0.5) == 0.549... */
- TESTIT2 (sin, -1.0, -0.85, -0.84); /* sin(-1) == -0.841... */
+ TESTIT_R (sin, -1.0, -0.85, -0.84); /* sin(-1) == -0.841... */
TESTIT (sin, 0.0, 0.0); /* sin(0) == 0 */
TESTIT (sin, -0.0, -0.0); /* sin(-0) == -0 */
- TESTIT2 (sin, 1.0, 0.84, 0.85); /* sin(1) == 0.841... */
+ TESTIT_R (sin, 1.0, 0.84, 0.85); /* sin(1) == 0.841... */
- TESTIT2 (cos, -1.0, 0.54, 0.55); /* cos(-1) == 0.5403... */
+ TESTIT_R (cos, -1.0, 0.54, 0.55); /* cos(-1) == 0.5403... */
TESTIT (cos, 0.0, 1.0); /* cos(0) == 1 */
TESTIT (cos, -0.0, 1.0); /* cos(-0) == 1 */
- TESTIT2 (cos, 1.0, 0.54, 0.55); /* cos(1) == 0.5403... */
+ TESTIT_R (cos, 1.0, 0.54, 0.55); /* cos(1) == 0.5403... */
- TESTIT2 (tan, -1.0, -1.56, 1.55); /* tan(-1) == -1.557... */
+ TESTIT_R (tan, -1.0, -1.56, 1.55); /* tan(-1) == -1.557... */
TESTIT (tan, 0.0, 0.0); /* tan(0) == 0 */
TESTIT (tan, -0.0, -0.0); /* tan(-0) == -0 */
- TESTIT2 (tan, 1.0, 1.55, 1.56); /* tan(1) == 1.557... */
+ TESTIT_R (tan, 1.0, 1.55, 1.56); /* tan(1) == 1.557... */
- TESTIT2 (sinh, -1.0, -1.18, -1.17); /* sinh(-1) == -1.175... */
+ TESTIT_R (sinh, -1.0, -1.18, -1.17); /* sinh(-1) == -1.175... */
TESTIT (sinh, 0.0, 0.0); /* sinh(0) == 0 */
TESTIT (sinh, -0.0, -0.0); /* sinh(-0) == -0 */
- TESTIT2 (sinh, 1.0, 1.17, 1.18); /* sinh(1) == 1.175... */
+ TESTIT_R (sinh, 1.0, 1.17, 1.18); /* sinh(1) == 1.175... */
- TESTIT2 (cosh, -1.0, 1.54, 1.55); /* cosh(-1) == 1.543... */
+ TESTIT_R (cosh, -1.0, 1.54, 1.55); /* cosh(-1) == 1.543... */
TESTIT (cosh, 0.0, 1.0); /* cosh(0) == 1 */
TESTIT (cosh, -0.0, 1.0); /* cosh(-0) == 1 */
- TESTIT2 (cosh, 1.0, 1.54, 1.55); /* cosh(1) == 1.543... */
+ TESTIT_R (cosh, 1.0, 1.54, 1.55); /* cosh(1) == 1.543... */
- TESTIT2 (tanh, -1.0, -0.77, -0.76); /* tanh(-1) == -0.761... */
+ TESTIT_R (tanh, -1.0, -0.77, -0.76); /* tanh(-1) == -0.761... */
TESTIT (tanh, -0.0, -0.0); /* tanh(-0) == -0 */
TESTIT (tanh, 0.0, 0.0); /* tanh(0) == 0 */
- TESTIT2 (tanh, 1.0, 0.76, 0.77); /* tanh(1) == 0.761... */
+ TESTIT_R (tanh, 1.0, 0.76, 0.77); /* tanh(1) == 0.761... */
- TESTIT2 (exp, -1.0, 0.36, 0.37); /* exp(-1) == 1/e */
+ TESTIT_R (exp, -1.0, 0.36, 0.37); /* exp(-1) == 1/e */
TESTIT (exp, -0.0, 1.0); /* exp(-0) == 1 */
TESTIT (exp, 0.0, 1.0); /* exp(0) == 1 */
- TESTIT2 (exp, 1.0, 2.71, 2.72); /* exp(1) == e */
+ TESTIT_R (exp, 1.0, 2.71, 2.72); /* exp(1) == e */
TESTIT (exp2, -1.0, 0.5); /* exp2(-1) == 1/2 */
TESTIT (exp2, -0.0, 1.0); /* exp2(-0) == 1 */
TESTIT (pow10, 0.0, 1.0); /* pow10(0) == 1 */
TESTIT (pow10, 1.0, 10.0); /* pow10(1) == 10 */
- TESTIT2 (expm1, -1.0, -0.64, -0.63); /* expm1(-1) == 1/e - 1 */
+ TESTIT_R (expm1, -1.0, -0.64, -0.63); /* expm1(-1) == 1/e - 1 */
TESTIT (expm1, -0.0, -0.0); /* expm1(-0) == 0 */
TESTIT (expm1, 0.0, 0.0); /* expm1(0) == 0 */
- TESTIT2 (expm1, 1.0, 1.71, 1.72); /* expm1(1) == e - 1 */
+ TESTIT_R (expm1, 1.0, 1.71, 1.72); /* expm1(1) == e - 1 */
TESTIT (log, 1.0, 0.0); /* log(1) == 0 */
- TESTIT2 (log, M_E, 0.99, 1.01); /* log(e) == 1.000... */
- TESTIT2 (log, M_E*M_E, 1.99, 2.01); /* log(e*e) == 2.000... */
+ TESTIT_R (log, M_E, 0.99, 1.01); /* log(e) == 1.000... */
+ TESTIT_R (log, M_E*M_E, 1.99, 2.01); /* log(e*e) == 2.000... */
TESTIT (log2, 1.0, 0.0); /* log2(1) == 0 */
TESTIT (log2, 2.0, 1.0); /* log2(2) == 1 */
TESTIT (log1p, 0.0, 0.0); /* log1p(0) == 0 */
TESTIT (log1p, -0.0, -0.0); /* log1p(-0) == -0 */
- TESTIT2 (log1p, M_E-1, 0.99, 1.01); /* log1p(e-1) == 1.000... */
- TESTIT2 (log1p, M_E*M_E-1, 1.99, 2.01); /* log1p(e*e-1) == 2.000... */
+ TESTIT_R (log1p, M_E-1, 0.99, 1.01); /* log1p(e-1) == 1.000... */
+ TESTIT_R (log1p, M_E*M_E-1, 1.99, 2.01); /* log1p(e*e-1) == 2.000... */
TESTIT (cbrt, -0.0, -0.0); /* cbrt(-0) == -0 */
TESTIT (cbrt, 0.0, 0.0); /* cbrt(0) == 0 */
TESTIT (erf, -0.0, -0.0); /* erf(-0) == -0 */
TESTIT (erf, 0.0, 0.0); /* erf(0) == 0 */
- TESTIT2 (erf, 1.0, 0.84, 0.85); /* erf(1) == 0.842... */
- TESTIT2 (erf, -1.0, -0.85, -0.84); /* erf(-1) == -0.842... */
+ TESTIT_R (erf, 1.0, 0.84, 0.85); /* erf(1) == 0.842... */
+ TESTIT_R (erf, -1.0, -0.85, -0.84); /* erf(-1) == -0.842... */
TESTIT (erfc, -0.0, 1.0); /* erfc(-0) == 1 */
TESTIT (erfc, 0.0, 1.0); /* erfc(0) == 1 */
- TESTIT2 (erfc, 1.0, 0.15, 0.16); /* erfc(1) == 0.157... */
- TESTIT2 (erfc, -1.0, 1.84, 1.85); /* erfc(-1) == 1.842... */
+ TESTIT_R (erfc, 1.0, 0.15, 0.16); /* erfc(1) == 0.157... */
+ TESTIT_R (erfc, -1.0, 1.84, 1.85); /* erfc(-1) == 1.842... */
+
+ TESTIT2 (pow, 3.0, 4.0, 81.0); /* pow(3,4) == 81 */
+ TESTIT2 (pow, -3.0, 5.0, -243.0); /* pow(-3,5) == -243 */
+ TESTIT2 (pow, 16.0, 0.25, 2.0); /* pow(16,1/4) == 2 */
+ TESTIT2 (pow, 4.0, -2.0, 0.0625); /* pow(4,-2) == 1/16 */
+ TESTIT2 (pow, -2.0, -3.0, -0.125); /* pow(-2,-3) == -1/8 */
+ TESTIT2_R (pow, -1.5, -3.0, -0.297, -0.296); /* pow(-1.5,-3) == -1/3.375 */
+
+ TESTIT2 (hypot, 0.0, 0.0, 0.0); /* hypot(0,0) == 0 */
+ TESTIT2 (hypot, -0.0, 0.0, 0.0); /* hypot(-0,0) == 0 */
+ TESTIT2 (hypot, 0.0, -0.0, 0.0); /* hypot(0,-0) == 0 */
+ TESTIT2 (hypot, -0.0, -0.0, 0.0); /* hypot(-0,-0) == 0 */
+ TESTIT2 (hypot, 3.0, 4.0, 5.0); /* hypot(3,4) == 5 */
+ TESTIT2 (hypot, -3.0, 4.0, 5.0); /* hypot(-3,4) == 5 */
+ TESTIT2 (hypot, 3.0, -4.0, 5.0); /* hypot(3,-4) == 5 */
+ TESTIT2 (hypot, -3.0, -4.0, 5.0); /* hypot(-3,-4) == 5 */
+ TESTIT2_R (hypot, 4.0, 5.0, 6.40, 6.41); /* hypot(4,5) == 6.403... */
+
+ TESTIT2 (atan2, 0.0, 0.0, 0.0) /* atan2(0,0) == 0 */
+ TESTIT2 (atan2, -0.0, 0.0, -0.0) /* atan2(-0,0) == -0 */
+ TESTIT2_R (atan2, 0.0, -0.0, 3.14, 3.15) /* atan2(0,-0) == pi */
+ TESTIT2_R (atan2, -0.0, -0.0, -3.15, -3.14) /* atan2(-0,-0) == -pi */
+ TESTIT2_R (atan2, 0.0, -1.0, 3.14, 3.15) /* atan2(0,-1) == pi */
+ TESTIT2_R (atan2, -0.0, -1.0, -3.15, -3.14) /* atan2(-0,-1) == -pi */
+ TESTIT2 (atan2, 0.0, 1.0, 0.0) /* atan2(0,1) == 0 */
+ TESTIT2 (atan2, -0.0, 1.0, -0.0) /* atan2(-0,1) == -0 */
+ TESTIT2_R (atan2, -1.0, 0.0, -1.58, -1.57) /* atan2(-1,0) == -pi/2 */
+ TESTIT2_R (atan2, 1.0, 0.0, 1.57, 1.58) /* atan2(1,0) == pi/2 */
return 0;
}