diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2007-01-06 02:28:38 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2007-01-06 02:28:38 +0000 |
commit | b2965b9fcee165a49fed4805c2649b753cb4f877 (patch) | |
tree | 9888da33ea137203d7ec41fb9b50509fdb61bfa8 /src/backend/utils/adt/float.c | |
parent | 561b4bae781d894dbfb75856f01779533cd09e05 (diff) | |
download | postgresql-b2965b9fcee165a49fed4805c2649b753cb4f877.tar.gz postgresql-b2965b9fcee165a49fed4805c2649b753cb4f877.zip |
Put back ERANGE test in dpow(). There are platforms that need this,
like my HPPA ...
Diffstat (limited to 'src/backend/utils/adt/float.c')
-rw-r--r-- | src/backend/utils/adt/float.c | 17 |
1 files changed, 10 insertions, 7 deletions
diff --git a/src/backend/utils/adt/float.c b/src/backend/utils/adt/float.c index 129405693f2..9cda3706afa 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.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); |