Put back ERANGE test in dpow(). There are platforms that need this,

like my HPPA ...
This commit is contained in:
Tom Lane 2007-01-06 02:28:38 +00:00
parent 561b4bae78
commit b2965b9fce
1 changed files with 10 additions and 7 deletions

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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 * pow() sets errno only on some platforms, depending on whether it
* follows _IEEE_, _POSIX_, _XOPEN_, or _SVID_, so we try to avoid * follows _IEEE_, _POSIX_, _XOPEN_, or _SVID_, so we try to avoid
* using errno. However, some platform/CPU combinations return * using errno. However, some platform/CPU combinations return
* errno == EDOM and result == Nan, so we have to check for that and * errno == EDOM and result == Nan for negative arg1 and very large arg2
* set result properly. For example, Linux on 32-bit x86 hardware * (they must be using something different from our floor() test to
* returns EDOM/Nan for (-1) ^ 1e19, but (-1) ^ 1e18 returns * decide it's invalid). Other platforms return errno == ERANGE and a
* 1 -- basically a negative base raised to a very high power causes * large but finite result to signal overflow.
* it on some CPUs.
*/ */
errno = 0; errno = 0;
result = pow(arg1, arg2); result = pow(arg1, arg2);
if (errno == EDOM && isnan(result)) if (errno == EDOM && isnan(result))
{ {
if ((fabs(arg1) > 1 && arg2 >= 0) || (fabs(arg1) < 1 && arg2 < 0)) 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(); result = get_float8_infinity();
else if (fabs(arg1) != 1) else if (fabs(arg1) != 1)
result = 0; result = 0;
else else
result = 1; result = 1;
} }
else if (errno == ERANGE)
{
result = (arg1 >= 0) ? get_float8_infinity() : -get_float8_infinity();
}
CHECKFLOATVAL(result, isinf(arg1) || isinf(arg2), arg1 == 0); CHECKFLOATVAL(result, isinf(arg1) || isinf(arg2), arg1 == 0);
PG_RETURN_FLOAT8(result); PG_RETURN_FLOAT8(result);