aboutsummaryrefslogtreecommitdiff
path: root/math/math-narrow.h
diff options
context:
space:
mode:
Diffstat (limited to 'math/math-narrow.h')
-rw-r--r--math/math-narrow.h53
1 files changed, 53 insertions, 0 deletions
diff --git a/math/math-narrow.h b/math/math-narrow.h
index f769830..c4065e8 100644
--- a/math/math-narrow.h
+++ b/math/math-narrow.h
@@ -219,6 +219,59 @@
} \
while (0)
+/* Check for error conditions from a narrowing divide function
+ returning RET with arguments X and Y and set errno as needed.
+ Overflow, underflow and divide-by-zero can occur for finite
+ arguments and a domain error for Inf / Inf and 0 / 0. */
+#define CHECK_NARROW_DIV(RET, X, Y) \
+ do \
+ { \
+ if (!isfinite (RET)) \
+ { \
+ if (isnan (RET)) \
+ { \
+ if (!isnan (X) && !isnan (Y)) \
+ __set_errno (EDOM); \
+ } \
+ else if (isfinite (X)) \
+ __set_errno (ERANGE); \
+ } \
+ else if ((RET) == 0 && (X) != 0 && !isinf (Y)) \
+ __set_errno (ERANGE); \
+ } \
+ while (0)
+
+/* Implement narrowing divide using round-to-odd. The arguments are
+ X and Y, the return type is TYPE and UNION, MANTISSA and SUFFIX are
+ as for ROUND_TO_ODD. */
+#define NARROW_DIV_ROUND_TO_ODD(X, Y, TYPE, UNION, SUFFIX, MANTISSA) \
+ do \
+ { \
+ TYPE ret; \
+ \
+ ret = (TYPE) ROUND_TO_ODD (math_opt_barrier (X) / (Y), \
+ UNION, SUFFIX, MANTISSA); \
+ \
+ CHECK_NARROW_DIV (ret, (X), (Y)); \
+ return ret; \
+ } \
+ while (0)
+
+/* Implement a narrowing divide function that is not actually
+ narrowing or where no attempt is made to be correctly rounding (the
+ latter only applies to IBM long double). The arguments are X and Y
+ and the return type is TYPE. */
+#define NARROW_DIV_TRIVIAL(X, Y, TYPE) \
+ do \
+ { \
+ TYPE ret; \
+ \
+ ret = (TYPE) ((X) / (Y)); \
+ CHECK_NARROW_DIV (ret, (X), (Y)); \
+ return ret; \
+ } \
+ while (0)
+
/* The following macros declare aliases for a narrowing function. The
sole argument is the base name of a family of functions, such as
"add". If any platform changes long double format after the