aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/float.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/utils/adt/float.c')
-rw-r--r--src/backend/utils/adt/float.c29
1 files changed, 23 insertions, 6 deletions
diff --git a/src/backend/utils/adt/float.c b/src/backend/utils/adt/float.c
index 2660bd3e31f..d4e551b5edb 100644
--- a/src/backend/utils/adt/float.c
+++ b/src/backend/utils/adt/float.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/adt/float.c,v 1.136 2007/01/03 04:21:47 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/float.c,v 1.137 2007/01/03 14:35:24 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -1440,11 +1440,19 @@ dpow(PG_FUNCTION_ARGS)
/*
* pow() sets errno only on some platforms, depending on whether it
- * follows _IEEE_, _POSIX_, _XOPEN_, or _SVID_, so, for consistency,
- * we don't consult it and just do our check below.
+ * follows _IEEE_, _POSIX_, _XOPEN_, or _SVID_, and some return Nan,
+ * so we check and set result properly.
*/
+ errno = 0;
result = pow(arg1, arg2);
-
+ if (errno == ERANGE && isnan(result))
+ {
+ if ((fabs(arg1) > 1 && arg2 >= 0) || (fabs(arg1) < 1 && arg2 < 0))
+ result = (arg1 >= 0) ? get_float8_infinity() : -get_float8_infinity();
+ else
+ result = 0;
+ }
+
CHECKFLOATVAL(result, isinf(arg1) || isinf(arg2), arg1 == 0);
PG_RETURN_FLOAT8(result);
}
@@ -1461,10 +1469,19 @@ dexp(PG_FUNCTION_ARGS)
/*
* exp() sets errno only on some platforms, depending on whether it
- * follows _IEEE_, _POSIX_, _XOPEN_, or _SVID_, so, for consistency,
- * we don't consult it and just do our check below.
+ * follows _IEEE_, _POSIX_, _XOPEN_, or _SVID_, and some return Nan,
+ * so we check and set result properly.
*/
+ errno = 0;
result = exp(arg1);
+ if (errno == ERANGE && isnan(result))
+ {
+ if (arg1 >= 0)
+ result = get_float8_infinity();
+ else
+ result = 0;
+ }
+
CHECKFLOATVAL(result, isinf(arg1), false);
PG_RETURN_FLOAT8(result);