summaryrefslogtreecommitdiff
path: root/libc/math
diff options
context:
space:
mode:
Diffstat (limited to 'libc/math')
-rw-r--r--libc/math/basic-test.c20
-rw-r--r--libc/math/libm-test.inc175
-rw-r--r--libc/math/s_cexp.c14
-rw-r--r--libc/math/s_cexpf.c14
-rw-r--r--libc/math/s_cexpl.c14
-rw-r--r--libc/math/s_cproj.c4
-rw-r--r--libc/math/s_cprojf.c4
-rw-r--r--libc/math/s_cprojl.c4
-rw-r--r--libc/math/s_fdim.c8
-rw-r--r--libc/math/s_fdimf.c8
-rw-r--r--libc/math/s_fdiml.c8
11 files changed, 203 insertions, 70 deletions
diff --git a/libc/math/basic-test.c b/libc/math/basic-test.c
index 9e9b848ee..44145a75f 100644
--- a/libc/math/basic-test.c
+++ b/libc/math/basic-test.c
@@ -148,7 +148,7 @@ NAME (void) \
check (#FLOAT " isinf (-HUGE_VALx) == -1", isinf (x1) == -1); \
}
-#define TEST_TRUNC(NAME, FLOAT, DOUBLE, SUFFIX) \
+#define TEST_CONVERT(NAME, FLOAT, DOUBLE, SUFFIX) \
void \
NAME (void) \
{ \
@@ -189,11 +189,14 @@ NAME (void) \
TEST_FUNC (float_test, float, f, FLT_EPSILON, HUGE_VALF)
TEST_FUNC (double_test, double, , DBL_EPSILON, HUGE_VAL)
-TEST_TRUNC (truncdfsf_test, float, double, )
+TEST_CONVERT (convert_dfsf_test, float, double, )
+TEST_CONVERT (convert_sfdf_test, double, float, f)
#ifndef NO_LONG_DOUBLE
TEST_FUNC (ldouble_test, long double, l, LDBL_EPSILON, HUGE_VALL)
-TEST_TRUNC (trunctfsf_test, float, long double, l)
-TEST_TRUNC (trunctfdf_test, double, long double, l)
+TEST_CONVERT (convert_tfsf_test, float, long double, l)
+TEST_CONVERT (convert_sftf_test, long double, float, f)
+TEST_CONVERT (convert_tfdf_test, double, long double, l)
+TEST_CONVERT (convert_dftf_test, long double, double, )
#endif
int
@@ -201,12 +204,15 @@ do_test (void)
{
float_test ();
double_test ();
- truncdfsf_test();
+ convert_dfsf_test();
+ convert_sfdf_test();
#ifndef NO_LONG_DOUBLE
ldouble_test ();
- trunctfsf_test();
- trunctfdf_test();
+ convert_tfsf_test();
+ convert_sftf_test();
+ convert_tfdf_test();
+ convert_dftf_test();
#endif
return errors != 0;
diff --git a/libc/math/libm-test.inc b/libc/math/libm-test.inc
index 851f1beaf..fe85bb9f1 100644
--- a/libc/math/libm-test.inc
+++ b/libc/math/libm-test.inc
@@ -6198,7 +6198,8 @@ static const struct test_c_c_data cexp_test_data[] =
TEST_c_c (cexp, plus_infty, qnan_value, plus_infty, qnan_value),
- TEST_c_c (cexp, qnan_value, 0.0, qnan_value, qnan_value, INVALID_EXCEPTION_OK),
+ TEST_c_c (cexp, qnan_value, 0.0, qnan_value, 0.0),
+ TEST_c_c (cexp, qnan_value, minus_zero, qnan_value, minus_zero),
TEST_c_c (cexp, qnan_value, 1.0, qnan_value, qnan_value, INVALID_EXCEPTION_OK),
TEST_c_c (cexp, qnan_value, plus_infty, qnan_value, qnan_value, INVALID_EXCEPTION_OK),
@@ -7066,11 +7067,51 @@ static const struct test_c_c_data cproj_test_data[] =
TEST_c_c (cproj, qnan_value, qnan_value, qnan_value, qnan_value, NO_INEXACT_EXCEPTION),
+ TEST_c_c (cproj, plus_zero, qnan_value, plus_zero, qnan_value, NO_INEXACT_EXCEPTION),
+ TEST_c_c (cproj, minus_zero, qnan_value, minus_zero, qnan_value, NO_INEXACT_EXCEPTION),
+ TEST_c_c (cproj, qnan_value, plus_zero, qnan_value, plus_zero, NO_INEXACT_EXCEPTION),
+ TEST_c_c (cproj, qnan_value, minus_zero, qnan_value, minus_zero, NO_INEXACT_EXCEPTION),
+
+ TEST_c_c (cproj, 1.0, qnan_value, 1.0, qnan_value, NO_INEXACT_EXCEPTION),
+ TEST_c_c (cproj, -1.0, qnan_value, -1.0, qnan_value, NO_INEXACT_EXCEPTION),
+ TEST_c_c (cproj, qnan_value, 1.0, qnan_value, 1.0, NO_INEXACT_EXCEPTION),
+ TEST_c_c (cproj, qnan_value, -1.0, qnan_value, -1.0, NO_INEXACT_EXCEPTION),
+
TEST_c_c (cproj, plus_infty, plus_infty, plus_infty, 0.0, NO_INEXACT_EXCEPTION),
TEST_c_c (cproj, plus_infty, minus_infty, plus_infty, minus_zero, NO_INEXACT_EXCEPTION),
TEST_c_c (cproj, minus_infty, plus_infty, plus_infty, 0.0, NO_INEXACT_EXCEPTION),
TEST_c_c (cproj, minus_infty, minus_infty, plus_infty, minus_zero, NO_INEXACT_EXCEPTION),
+ TEST_c_c (cproj, plus_infty, plus_zero, plus_infty, 0.0, NO_INEXACT_EXCEPTION),
+ TEST_c_c (cproj, plus_infty, minus_zero, plus_infty, minus_zero, NO_INEXACT_EXCEPTION),
+ TEST_c_c (cproj, minus_infty, plus_zero, plus_infty, 0.0, NO_INEXACT_EXCEPTION),
+ TEST_c_c (cproj, minus_infty, minus_zero, plus_infty, minus_zero, NO_INEXACT_EXCEPTION),
+
+ TEST_c_c (cproj, plus_zero, plus_infty, plus_infty, 0.0, NO_INEXACT_EXCEPTION),
+ TEST_c_c (cproj, plus_zero, minus_infty, plus_infty, minus_zero, NO_INEXACT_EXCEPTION),
+ TEST_c_c (cproj, minus_zero, plus_infty, plus_infty, 0.0, NO_INEXACT_EXCEPTION),
+ TEST_c_c (cproj, minus_zero, minus_infty, plus_infty, minus_zero, NO_INEXACT_EXCEPTION),
+
+ TEST_c_c (cproj, plus_infty, 1.0, plus_infty, 0.0, NO_INEXACT_EXCEPTION),
+ TEST_c_c (cproj, plus_infty, -1.0, plus_infty, minus_zero, NO_INEXACT_EXCEPTION),
+ TEST_c_c (cproj, minus_infty, 1.0, plus_infty, 0.0, NO_INEXACT_EXCEPTION),
+ TEST_c_c (cproj, minus_infty, -1.0, plus_infty, minus_zero, NO_INEXACT_EXCEPTION),
+
+ TEST_c_c (cproj, 1.0, plus_infty, plus_infty, 0.0, NO_INEXACT_EXCEPTION),
+ TEST_c_c (cproj, 1.0, minus_infty, plus_infty, minus_zero, NO_INEXACT_EXCEPTION),
+ TEST_c_c (cproj, -1.0, plus_infty, plus_infty, 0.0, NO_INEXACT_EXCEPTION),
+ TEST_c_c (cproj, -1.0, minus_infty, plus_infty, minus_zero, NO_INEXACT_EXCEPTION),
+
+ TEST_c_c (cproj, plus_infty, qnan_value, plus_infty, 0.0, NO_INEXACT_EXCEPTION),
+ TEST_c_c (cproj, plus_infty, -qnan_value, plus_infty, minus_zero, NO_INEXACT_EXCEPTION),
+ TEST_c_c (cproj, minus_infty, qnan_value, plus_infty, 0.0, NO_INEXACT_EXCEPTION),
+ TEST_c_c (cproj, minus_infty, -qnan_value, plus_infty, minus_zero, NO_INEXACT_EXCEPTION),
+
+ TEST_c_c (cproj, qnan_value, plus_infty, plus_infty, 0.0, NO_INEXACT_EXCEPTION),
+ TEST_c_c (cproj, qnan_value, minus_infty, plus_infty, minus_zero, NO_INEXACT_EXCEPTION),
+ TEST_c_c (cproj, -qnan_value, plus_infty, plus_infty, 0.0, NO_INEXACT_EXCEPTION),
+ TEST_c_c (cproj, -qnan_value, minus_infty, plus_infty, minus_zero, NO_INEXACT_EXCEPTION),
+
TEST_c_c (cproj, 1.0, 0.0, 1.0, 0.0, NO_INEXACT_EXCEPTION),
TEST_c_c (cproj, 2.0, 3.0, 2.0, 3.0, NO_INEXACT_EXCEPTION),
};
@@ -8104,33 +8145,37 @@ fabs_test (void)
static const struct test_ff_f_data fdim_test_data[] =
{
- TEST_ff_f (fdim, 0, 0, 0, NO_INEXACT_EXCEPTION),
- TEST_ff_f (fdim, 9, 0, 9, NO_INEXACT_EXCEPTION),
- TEST_ff_f (fdim, 0, 9, 0, NO_INEXACT_EXCEPTION),
- TEST_ff_f (fdim, -9, 0, 0, NO_INEXACT_EXCEPTION),
- TEST_ff_f (fdim, 0, -9, 9, NO_INEXACT_EXCEPTION),
-
- TEST_ff_f (fdim, plus_infty, 9, plus_infty, NO_INEXACT_EXCEPTION),
- TEST_ff_f (fdim, plus_infty, -9, plus_infty, NO_INEXACT_EXCEPTION),
- TEST_ff_f (fdim, minus_infty, 9, 0, NO_INEXACT_EXCEPTION),
- TEST_ff_f (fdim, minus_infty, -9, 0, NO_INEXACT_EXCEPTION),
- TEST_ff_f (fdim, 9, minus_infty, plus_infty, NO_INEXACT_EXCEPTION),
- TEST_ff_f (fdim, -9, minus_infty, plus_infty, NO_INEXACT_EXCEPTION),
- TEST_ff_f (fdim, 9, plus_infty, 0, NO_INEXACT_EXCEPTION),
- TEST_ff_f (fdim, -9, plus_infty, 0, NO_INEXACT_EXCEPTION),
-
- TEST_ff_f (fdim, 0, qnan_value, qnan_value, NO_INEXACT_EXCEPTION),
- TEST_ff_f (fdim, 9, qnan_value, qnan_value, NO_INEXACT_EXCEPTION),
- TEST_ff_f (fdim, -9, qnan_value, qnan_value, NO_INEXACT_EXCEPTION),
- TEST_ff_f (fdim, qnan_value, 9, qnan_value, NO_INEXACT_EXCEPTION),
- TEST_ff_f (fdim, qnan_value, -9, qnan_value, NO_INEXACT_EXCEPTION),
- TEST_ff_f (fdim, plus_infty, qnan_value, qnan_value, NO_INEXACT_EXCEPTION),
- TEST_ff_f (fdim, minus_infty, qnan_value, qnan_value, NO_INEXACT_EXCEPTION),
- TEST_ff_f (fdim, qnan_value, plus_infty, qnan_value, NO_INEXACT_EXCEPTION),
- TEST_ff_f (fdim, qnan_value, minus_infty, qnan_value, NO_INEXACT_EXCEPTION),
- TEST_ff_f (fdim, qnan_value, qnan_value, qnan_value, NO_INEXACT_EXCEPTION),
-
- TEST_ff_f (fdim, plus_infty, plus_infty, 0, NO_INEXACT_EXCEPTION),
+ TEST_ff_f (fdim, 0, 0, 0, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+ TEST_ff_f (fdim, 9, 0, 9, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+ TEST_ff_f (fdim, 0, 9, 0, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+ TEST_ff_f (fdim, -9, 0, 0, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+ TEST_ff_f (fdim, 0, -9, 9, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+
+ TEST_ff_f (fdim, plus_infty, 9, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+ TEST_ff_f (fdim, plus_infty, -9, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+ TEST_ff_f (fdim, minus_infty, 9, 0, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+ TEST_ff_f (fdim, minus_infty, -9, 0, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+ TEST_ff_f (fdim, 9, minus_infty, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+ TEST_ff_f (fdim, -9, minus_infty, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+ TEST_ff_f (fdim, 9, plus_infty, 0, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+ TEST_ff_f (fdim, -9, plus_infty, 0, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+
+ TEST_ff_f (fdim, 0, qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+ TEST_ff_f (fdim, 9, qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+ TEST_ff_f (fdim, -9, qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+ TEST_ff_f (fdim, qnan_value, 0, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+ TEST_ff_f (fdim, qnan_value, 9, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+ TEST_ff_f (fdim, qnan_value, -9, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+ TEST_ff_f (fdim, plus_infty, qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+ TEST_ff_f (fdim, minus_infty, qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+ TEST_ff_f (fdim, qnan_value, plus_infty, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+ TEST_ff_f (fdim, qnan_value, minus_infty, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+ TEST_ff_f (fdim, qnan_value, qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+
+ TEST_ff_f (fdim, plus_infty, plus_infty, 0, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+ TEST_ff_f (fdim, plus_infty, minus_infty, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+ TEST_ff_f (fdim, minus_infty, plus_infty, 0, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+ TEST_ff_f (fdim, minus_infty, minus_infty, 0, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
};
static void
@@ -9868,8 +9913,14 @@ static const struct test_if_f_data jn_test_data[] =
TEST_if_f (jn, 8, 2.4048255576957729L, 0.92165786705344923232879022467054148E-4L),
TEST_if_f (jn, 9, 2.4048255576957729L, 0.12517270977961513005428966643852564E-4L),
- /* Bug 14155: spurious exception may occur. */
- TEST_if_f (jn, 2, 0x1.ffff62p+99L, -4.43860668048170034334926693188979974489e-16L, UNDERFLOW_EXCEPTION_OK),
+ TEST_if_f (jn, 2, 0x1.ffff62p+99L, -4.43860668048170034334926693188979974489e-16L),
+ TEST_if_f (jn, 2, 0x1p127L, -6.0784021821505059176832624052765568656702e-20L),
+#ifndef TEST_FLOAT
+ TEST_if_f (jn, 2, 0x1p1023L, 1.5665258060609012834424478437196679802783e-155L),
+#endif
+#if defined TEST_LDOUBLE && LDBL_MAX_EXP >= 16384
+ TEST_if_f (jn, 2, 0x1p16383L, -9.5859502826270374691362975419147645151233e-2467L),
+#endif
};
static void
@@ -9927,6 +9978,61 @@ static const struct test_f_f1_data lgamma_test_data[] =
TEST_f_f1 (lgamma, -0.5, M_LOG_2_SQRT_PIl, -1),
TEST_f_f1 (lgamma, 0.7L, 0.260867246531666514385732417016759578L, 1),
TEST_f_f1 (lgamma, 1.2L, -0.853740900033158497197028392998854470e-1L, 1),
+
+ TEST_f_f1 (lgamma, 0x1p-5L, 3.4484891277979584796832693452686366085801e+00L, 1),
+ TEST_f_f1 (lgamma, -0x1p-5L, 3.4845895751341394376217526729956836492792e+00L, -1),
+ TEST_f_f1 (lgamma, 0x1p-10L, 6.9309089024194618895406190646600805357273e+00L, 1),
+ TEST_f_f1 (lgamma, -0x1p-10L, 6.9320362775113082175565786721095494761582e+00L, -1),
+ TEST_f_f1 (lgamma, 0x1p-15L, 1.0397190093941001762077888432721419773538e+01L, 1),
+ TEST_f_f1 (lgamma, -0x1p-15L, 1.0397225324389321751118257981741350715545e+01L, -1),
+ TEST_f_f1 (lgamma, 0x1p-20L, 1.3862943060723899573457963336920089012399e+01L, 1),
+ TEST_f_f1 (lgamma, -0x1p-20L, 1.3862944161675408862049886226750366625112e+01L, -1),
+ TEST_f_f1 (lgamma, 0x1p-25L, 1.7328679496796266133304874243201700664713e+01L, 1),
+ TEST_f_f1 (lgamma, -0x1p-25L, 1.7328679531201000798551671833865469674673e+01L, -1),
+ TEST_f_f1 (lgamma, 0x1p-30L, 2.0794415416260785304085859198055798098863e+01L, 1),
+ TEST_f_f1 (lgamma, -0x1p-30L, 2.0794415417335933262374820960532606449975e+01L, -1),
+ TEST_f_f1 (lgamma, 0x1p-40L, 2.7725887222397287402100277256545578941303e+01L, 1),
+ TEST_f_f1 (lgamma, -0x1p-40L, 2.7725887222398337351278293820766115529596e+01L, -1),
+ TEST_f_f1 (lgamma, 0x1p-50L, 3.4657359027997264958191108994508978906983e+01L, 1),
+ TEST_f_f1 (lgamma, -0x1p-50L, 3.4657359027997265983532103151309975524744e+01L, -1),
+ TEST_f_f1 (lgamma, 0x1p-60L, 4.1588830833596718564533272505187468598519e+01L, 1),
+ TEST_f_f1 (lgamma, -0x1p-60L, 4.1588830833596718565534582069793719571779e+01L, -1),
+ TEST_f_f1 (lgamma, 0x1p-64L, 4.4361419555836499802671564849429355013920e+01L, 1),
+ TEST_f_f1 (lgamma, -0x1p-64L, 4.4361419555836499802734146697217245699749e+01L, -1),
+ TEST_f_f1 (lgamma, 0x1p-70L, 4.8520302639196171659205759581386516869302e+01L, 1),
+ TEST_f_f1 (lgamma, -0x1p-70L, 4.8520302639196171659206737422758202661268e+01L, -1),
+ TEST_f_f1 (lgamma, 0x1p-100L, 6.9314718055994530941723212145817201464678e+01L, 1),
+ TEST_f_f1 (lgamma, -0x1p-100L, 6.9314718055994530941723212145818112150422e+01L, -1),
+ TEST_f_f1 (lgamma, 0x1p-126L, 8.7336544750553108986571247303730247577506e+01L, 1),
+ TEST_f_f1 (lgamma, -0x1p-126L, 8.7336544750553108986571247303730247577520e+01L, -1),
+ TEST_f_f1 (lgamma, 0x1p-149L, 1.0327892990343185110316758609726830864325e+02L, 1),
+ TEST_f_f1 (lgamma, -0x1p-149L, 1.0327892990343185110316758609726830864325e+02L, -1),
+#ifndef TEST_FLOAT
+ TEST_f_f1 (lgamma, 0x1p-200L, 1.3862943611198906188344642429163531361510e+02L, 1),
+ TEST_f_f1 (lgamma, -0x1p-200L, 1.3862943611198906188344642429163531361510e+02L, -1),
+ TEST_f_f1 (lgamma, 0x1p-500L, 3.4657359027997265470861606072908828403775e+02L, 1),
+ TEST_f_f1 (lgamma, -0x1p-500L, 3.4657359027997265470861606072908828403775e+02L, -1),
+ TEST_f_f1 (lgamma, 0x1p-1000L, 6.9314718055994530941723212145817656807550e+02L, 1),
+ TEST_f_f1 (lgamma, -0x1p-1000L, 6.9314718055994530941723212145817656807550e+02L, -1),
+ TEST_f_f1 (lgamma, 0x1p-1022L, 7.0839641853226410622441122813025645257316e+02L, 1),
+ TEST_f_f1 (lgamma, -0x1p-1022L, 7.0839641853226410622441122813025645257316e+02L, -1),
+ TEST_f_f1 (lgamma, 0x1p-1074L, 7.4444007192138126231410729844608163411309e+02L, 1),
+ TEST_f_f1 (lgamma, -0x1p-1074L, 7.4444007192138126231410729844608163411309e+02L, -1),
+#endif
+#if defined TEST_LDOUBLE && LDBL_MIN_EXP <= -16381
+ TEST_f_f1 (lgamma, 0x1p-5000L, 3.4657359027997265470861606072908828403775e+03L, 1),
+ TEST_f_f1 (lgamma, -0x1p-5000L, 3.4657359027997265470861606072908828403775e+03L, -1),
+ TEST_f_f1 (lgamma, 0x1p-10000L, 6.9314718055994530941723212145817656807550e+03L, 1),
+ TEST_f_f1 (lgamma, -0x1p-10000L, 6.9314718055994530941723212145817656807550e+03L, -1),
+ TEST_f_f1 (lgamma, 0x1p-16382L, 1.1355137111933024058873096613727848538213e+04L, 1),
+ TEST_f_f1 (lgamma, -0x1p-16382L, 1.1355137111933024058873096613727848538213e+04L, -1),
+ TEST_f_f1 (lgamma, 0x1p-16445L, 1.1398805384308300613366382237379713662002e+04L, 1),
+ TEST_f_f1 (lgamma, -0x1p-16445L, 1.1398805384308300613366382237379713662002e+04L, -1),
+# if LDBL_MANT_DIG >= 113
+ TEST_f_f1 (lgamma, 0x1p-16494L, 1.1432769596155737933527826611331164313837e+04L, 1),
+ TEST_f_f1 (lgamma, -0x1p-16494L, 1.1432769596155737933527826611331164313837e+04L, -1),
+# endif
+#endif
};
static void
@@ -14486,6 +14592,15 @@ static const struct test_if_f_data yn_test_data[] =
/* Check whether yn returns correct value for LDBL_MIN, DBL_MIN,
and FLT_MIN. See Bug 14173. */
TEST_if_f (yn, 10, min_value, minus_infty, OVERFLOW_EXCEPTION|ERRNO_ERANGE),
+
+ TEST_if_f (yn, 2, 0x1.ffff62p+99L, -5.5244413477397111790415387179517953221757e-16L),
+ TEST_if_f (yn, 2, 0x1p127L, 6.8569250690166637098111268958532649249771e-21L),
+#ifndef TEST_FLOAT
+ TEST_if_f (yn, 2, 0x1p1023L, -8.2687542933709649327986678723012001545638e-155L),
+#endif
+#if defined TEST_LDOUBLE && LDBL_MAX_EXP >= 16384
+ TEST_if_f (yn, 2, 0x1p16383L, 3.8895531955766020648617743624167352352217e-2467L),
+#endif
};
static void
diff --git a/libc/math/s_cexp.c b/libc/math/s_cexp.c
index 655e4e8de..40e0e518d 100644
--- a/libc/math/s_cexp.c
+++ b/libc/math/s_cexp.c
@@ -145,12 +145,18 @@ __cexp (__complex__ double x)
}
else
{
- /* If the real part is NaN the result is NaN + iNaN. */
+ /* If the real part is NaN the result is NaN + iNaN unless the
+ imaginary part is zero. */
__real__ retval = __nan ("");
- __imag__ retval = __nan ("");
+ if (icls == FP_ZERO)
+ __imag__ retval = __imag__ x;
+ else
+ {
+ __imag__ retval = __nan ("");
- if (rcls != FP_NAN || icls != FP_NAN)
- feraiseexcept (FE_INVALID);
+ if (rcls != FP_NAN || icls != FP_NAN)
+ feraiseexcept (FE_INVALID);
+ }
}
return retval;
diff --git a/libc/math/s_cexpf.c b/libc/math/s_cexpf.c
index fa942d34f..7c4220516 100644
--- a/libc/math/s_cexpf.c
+++ b/libc/math/s_cexpf.c
@@ -145,12 +145,18 @@ __cexpf (__complex__ float x)
}
else
{
- /* If the real part is NaN the result is NaN + iNaN. */
+ /* If the real part is NaN the result is NaN + iNaN unless the
+ imaginary part is zero. */
__real__ retval = __nanf ("");
- __imag__ retval = __nanf ("");
+ if (icls == FP_ZERO)
+ __imag__ retval = __imag__ x;
+ else
+ {
+ __imag__ retval = __nanf ("");
- if (rcls != FP_NAN || icls != FP_NAN)
- feraiseexcept (FE_INVALID);
+ if (rcls != FP_NAN || icls != FP_NAN)
+ feraiseexcept (FE_INVALID);
+ }
}
return retval;
diff --git a/libc/math/s_cexpl.c b/libc/math/s_cexpl.c
index d827bc3de..0c3560336 100644
--- a/libc/math/s_cexpl.c
+++ b/libc/math/s_cexpl.c
@@ -145,12 +145,18 @@ __cexpl (__complex__ long double x)
}
else
{
- /* If the real part is NaN the result is NaN + iNaN. */
+ /* If the real part is NaN the result is NaN + iNaN unless the
+ imaginary part is zero. */
__real__ retval = __nanl ("");
- __imag__ retval = __nanl ("");
+ if (icls == FP_ZERO)
+ __imag__ retval = __imag__ x;
+ else
+ {
+ __imag__ retval = __nanl ("");
- if (rcls != FP_NAN || icls != FP_NAN)
- feraiseexcept (FE_INVALID);
+ if (rcls != FP_NAN || icls != FP_NAN)
+ feraiseexcept (FE_INVALID);
+ }
}
return retval;
diff --git a/libc/math/s_cproj.c b/libc/math/s_cproj.c
index c0be4618d..98f1a4c4b 100644
--- a/libc/math/s_cproj.c
+++ b/libc/math/s_cproj.c
@@ -24,9 +24,7 @@
__complex__ double
__cproj (__complex__ double x)
{
- if (isnan (__real__ x) && isnan (__imag__ x))
- return x;
- else if (!isfinite (__real__ x) || !isfinite (__imag__ x))
+ if (__isinf_ns (__real__ x) || __isinf_ns (__imag__ x))
{
__complex__ double res;
diff --git a/libc/math/s_cprojf.c b/libc/math/s_cprojf.c
index 188bbe3be..e4dbc181b 100644
--- a/libc/math/s_cprojf.c
+++ b/libc/math/s_cprojf.c
@@ -24,9 +24,7 @@
__complex__ float
__cprojf (__complex__ float x)
{
- if (isnan (__real__ x) && isnan (__imag__ x))
- return x;
- else if (!isfinite (__real__ x) || !isfinite (__imag__ x))
+ if (__isinf_nsf (__real__ x) || __isinf_nsf (__imag__ x))
{
__complex__ float res;
diff --git a/libc/math/s_cprojl.c b/libc/math/s_cprojl.c
index fbdf2797e..b564a83e6 100644
--- a/libc/math/s_cprojl.c
+++ b/libc/math/s_cprojl.c
@@ -24,9 +24,7 @@
__complex__ long double
__cprojl (__complex__ long double x)
{
- if (isnan (__real__ x) && isnan (__imag__ x))
- return x;
- else if (!isfinite (__real__ x) || !isfinite (__imag__ x))
+ if (__isinf_nsl (__real__ x) || __isinf_nsl (__imag__ x))
{
__complex__ long double res;
diff --git a/libc/math/s_fdim.c b/libc/math/s_fdim.c
index 2f97948b2..f8fd80490 100644
--- a/libc/math/s_fdim.c
+++ b/libc/math/s_fdim.c
@@ -26,16 +26,16 @@ __fdim (double x, double y)
int clsx = fpclassify (x);
int clsy = fpclassify (y);
- if (clsx == FP_NAN || clsy == FP_NAN
- || (y < 0 && clsx == FP_INFINITE && clsy == FP_INFINITE))
- /* Raise invalid flag. */
+ if (clsx == FP_NAN || clsy == FP_NAN)
+ /* Raise invalid flag for signaling but not quiet NaN. */
return x - y;
if (x <= y)
return 0.0;
double r = x - y;
- if (fpclassify (r) == FP_INFINITE)
+ if (fpclassify (r) == FP_INFINITE
+ && clsx != FP_INFINITE && clsy != FP_INFINITE)
__set_errno (ERANGE);
return r;
diff --git a/libc/math/s_fdimf.c b/libc/math/s_fdimf.c
index 03810b572..86efe6ef2 100644
--- a/libc/math/s_fdimf.c
+++ b/libc/math/s_fdimf.c
@@ -26,16 +26,16 @@ __fdimf (float x, float y)
int clsx = fpclassify (x);
int clsy = fpclassify (y);
- if (clsx == FP_NAN || clsy == FP_NAN
- || (y < 0 && clsx == FP_INFINITE && clsy == FP_INFINITE))
- /* Raise invalid flag. */
+ if (clsx == FP_NAN || clsy == FP_NAN)
+ /* Raise invalid flag for signaling but not quiet NaN. */
return x - y;
if (x <= y)
return 0.0f;
float r = x - y;
- if (fpclassify (r) == FP_INFINITE)
+ if (fpclassify (r) == FP_INFINITE
+ && clsx != FP_INFINITE && clsy != FP_INFINITE)
__set_errno (ERANGE);
return r;
diff --git a/libc/math/s_fdiml.c b/libc/math/s_fdiml.c
index 56045329a..030fcc22e 100644
--- a/libc/math/s_fdiml.c
+++ b/libc/math/s_fdiml.c
@@ -26,16 +26,16 @@ __fdiml (long double x, long double y)
int clsx = fpclassify (x);
int clsy = fpclassify (y);
- if (clsx == FP_NAN || clsy == FP_NAN
- || (y < 0 && clsx == FP_INFINITE && clsy == FP_INFINITE))
- /* Raise invalid flag. */
+ if (clsx == FP_NAN || clsy == FP_NAN)
+ /* Raise invalid flag for signaling but not quiet NaN. */
return x - y;
if (x <= y)
return 0.0f;
long double r = x - y;
- if (fpclassify (r) == FP_INFINITE)
+ if (fpclassify (r) == FP_INFINITE
+ && clsx != FP_INFINITE && clsy != FP_INFINITE)
__set_errno (ERANGE);
return r;