Put back ERANGE test in dpow(). There are platforms that need this,
authorTom Lane
Sat, 6 Jan 2007 02:28:38 +0000 (02:28 +0000)
committerTom Lane
Sat, 6 Jan 2007 02:28:38 +0000 (02:28 +0000)
like my HPPA ...

src/backend/utils/adt/float.c

index 129405693f2ed9003f4947f3ec6dc332cbca4e37..9cda3706afa4da887246dc6bf8af91edfd856021 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/utils/adt/float.c,v 1.142 2007/01/05 22:19:40 momjian Exp $
+ *   $PostgreSQL: pgsql/src/backend/utils/adt/float.c,v 1.143 2007/01/06 02:28:38 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1442,24 +1442,27 @@ dpow(PG_FUNCTION_ARGS)
     * pow() sets errno only on some platforms, depending on whether it
     * follows _IEEE_, _POSIX_, _XOPEN_, or _SVID_, so we try to avoid
     * using errno.  However, some platform/CPU combinations return
-    * errno == EDOM and result == Nan, so we have to check for that and
-    * set result properly.  For example, Linux on 32-bit x86 hardware
-    * returns EDOM/Nan for (-1) ^ 1e19, but (-1) ^ 1e18 returns
-    * 1 -- basically a negative base raised to a very high power causes
-    * it on some CPUs.
+    * errno == EDOM and result == Nan for negative arg1 and very large arg2
+    * (they must be using something different from our floor() test to
+    * decide it's invalid).  Other platforms return errno == ERANGE and a
+    * large but finite result to signal overflow.
     */
    errno = 0;
    result = pow(arg1, arg2);
    if (errno == EDOM && isnan(result))
    {
        if ((fabs(arg1) > 1 && arg2 >= 0) || (fabs(arg1) < 1 && arg2 < 0))
-           /* The sign if Inf is not significant in this case. */
+           /* The sign of Inf is not significant in this case. */
            result = get_float8_infinity();
        else if (fabs(arg1) != 1)
            result = 0;
        else
            result = 1;
    }
+   else if (errno == ERANGE)
+   {
+       result = (arg1 >= 0) ? get_float8_infinity() : -get_float8_infinity();
+   }
    
    CHECKFLOATVAL(result, isinf(arg1) || isinf(arg2), arg1 == 0);
    PG_RETURN_FLOAT8(result);