]> granicus.if.org Git - postgresql/commitdiff
Attempt to return proper overflow/underflow messages for platforms that
authorBruce Momjian <bruce@momjian.us>
Wed, 3 Jan 2007 14:35:24 +0000 (14:35 +0000)
committerBruce Momjian <bruce@momjian.us>
Wed, 3 Jan 2007 14:35:24 +0000 (14:35 +0000)
only return Nan and set errno for pow/exp overflow/underflow.

src/backend/utils/adt/float.c

index 2660bd3e31fc4fce01549b145d6b6881ccbac12e..d4e551b5edb5231f1aa4be6726054b1e8af8c60d 100644 (file)
@@ -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);