aboutsummaryrefslogtreecommitdiff
path: root/math/test/trigpi_references.h
diff options
context:
space:
mode:
Diffstat (limited to 'math/test/trigpi_references.h')
-rw-r--r--math/test/trigpi_references.h106
1 files changed, 106 insertions, 0 deletions
diff --git a/math/test/trigpi_references.h b/math/test/trigpi_references.h
new file mode 100644
index 000000000000..3dc5a3173436
--- /dev/null
+++ b/math/test/trigpi_references.h
@@ -0,0 +1,106 @@
+/*
+ * Extended precision scalar reference functions for trigpi.
+ *
+ * Copyright (c) 2023-2024, Arm Limited.
+ * SPDX-License-Identifier: MIT OR Apache-2.0 WITH LLVM-exception
+ */
+
+#include "math_config.h"
+
+#ifndef M_PIl
+# define M_PIl 3.141592653589793238462643383279502884l
+#endif
+
+long double
+arm_math_sinpil (long double x)
+{
+ /* sin(inf) should return nan, as defined by C23. */
+ if (isinf (x))
+ return __math_invalid (x);
+
+ long double ax = fabsl (x);
+
+ /* Return 0 for all values above 2^64 to prevent
+ overflow when casting to uint64_t. */
+ if (ax >= 0x1p64)
+ return x < 0 ? -0.0l : 0.0l;
+
+ /* All integer cases should return 0, with unchanged sign for zero. */
+ if (x == 0.0l)
+ return x;
+ if (ax == (uint64_t) ax)
+ return x < 0 ? -0.0l : 0.0l;
+
+ return sinl (x * M_PIl);
+}
+
+long double
+arm_math_cospil (long double x)
+{
+ /* cos(inf) should return nan, as defined by C23. */
+ if (isinf (x))
+ return __math_invalid (x);
+
+ long double ax = fabsl (x);
+
+ if (ax >= 0x1p64)
+ return 1;
+
+ uint64_t m = (uint64_t) ax;
+
+ /* Integer values of cospi(x) should return +/-1.
+ The sign depends on if x is odd or even. */
+ if (m == ax)
+ return (m & 1) ? -1 : 1;
+
+ /* Values of Integer + 0.5 should always return 0. */
+ if (ax - 0.5 == m || ax + 0.5 == m)
+ return 0;
+
+ return cosl (ax * M_PIl);
+}
+
+long double
+arm_math_tanpil (long double x)
+{
+ /* inf and x = n + 0.5 for any integral n should return nan. */
+ if (fabsl (x) >= 0x1p54l)
+ {
+ if (isinf (x))
+ return __math_invalid (x);
+ return x < 0 ? -0.0l : 0.0l;
+ }
+
+ long double i = roundl (x);
+ long double f = x - i;
+ int64_t m = (int64_t) i;
+
+ if (x == 0)
+ {
+ return x;
+ }
+ else if (x == i)
+ {
+ if (x < 0)
+ {
+ return m & 1 ? 0.0l : -0.0l;
+ }
+ else
+ {
+ return m & 1 ? -0.0l : 0.0l;
+ }
+ }
+ else if (fabsl (f) == 0.5l)
+ {
+ if (x < 0)
+ {
+ return m & 1 ? -1.0l / 0.0l : 1.0l / 0.0l;
+ }
+ else
+ {
+ return m & 1 ? 1.0l / 0.0l : -1.0l / 0.0l;
+ }
+ }
+
+ return tanl (f * M_PIl);
+}