88 *
99 *
1010 * IDENTIFICATION
11- * $PostgreSQL: pgsql/src/backend/utils/adt/float.c,v 1.138 2007/01/0319:34:23 tgl Exp $
11+ * $PostgreSQL: pgsql/src/backend/utils/adt/float.c,v 1.139 2007/01/0322:05:00 momjian Exp $
1212 *
1313 *-------------------------------------------------------------------------
1414 */
@@ -1440,17 +1440,24 @@ dpow(PG_FUNCTION_ARGS)
14401440
14411441/*
14421442 * pow() sets errno only on some platforms, depending on whether it
1443- * follows _IEEE_, _POSIX_, _XOPEN_, or _SVID_, and some return Nan,
1444- * so we check and set result properly.
1443+ * follows _IEEE_, _POSIX_, _XOPEN_, or _SVID_, so we try to avoid
1444+ * using errno. However, some platform/CPU combinations return
1445+ * errno == EDOM and result == Nan, so we have to check for that and
1446+ * set result properly. For example, Linux on Pentium, pre-Xeon
1447+ * hardware returns EDOM/Nan for (-1) ^ 1e19, but (-1) ^ 1e18 retuns
1448+ * 1 -- basically a negative base raised to a very high power causes
1449+ * it on some CPUs.
14451450 */
14461451errno = 0 ;
14471452result = pow (arg1 ,arg2 );
1448- if (errno == ERANGE || isnan (result ))
1453+ if (errno == EDOM && isnan (result ))
14491454{
14501455if ((fabs (arg1 )> 1 && arg2 >=0 )|| (fabs (arg1 )< 1 && arg2 < 0 ))
14511456result = (arg1 >=0 ) ?get_float8_infinity () :- get_float8_infinity ();
1452- else
1457+ else if ( fabs ( arg1 ) != 1 )
14531458result = 0 ;
1459+ else
1460+ result = 1 ;
14541461}
14551462
14561463CHECKFLOATVAL (result ,isinf (arg1 )|| isinf (arg2 ),arg1 == 0 );
@@ -1467,20 +1474,7 @@ dexp(PG_FUNCTION_ARGS)
14671474float8 arg1 = PG_GETARG_FLOAT8 (0 );
14681475float8 result ;
14691476
1470- /*
1471- * exp() sets errno only on some platforms, depending on whether it
1472- * follows _IEEE_, _POSIX_, _XOPEN_, or _SVID_, and some return Nan,
1473- * so we check and set result properly.
1474- */
1475- errno = 0 ;
14761477result = exp (arg1 );
1477- if (errno == ERANGE || isnan (result ))
1478- {
1479- if (arg1 >=0 )
1480- result = get_float8_infinity ();
1481- else
1482- result = 0 ;
1483- }
14841478
14851479CHECKFLOATVAL (result ,isinf (arg1 ), false);
14861480PG_RETURN_FLOAT8 (result );