Skip to content

Commit 9c88830

Browse files
committed
Update pow() tests to check for both errno==EDOM _and_ result==Nan, and
document why this happens. Remove exp() errno check because not needed.
1 parent 812095d commit 9c88830

File tree

1 file changed

+12
-18
lines changed

1 file changed

+12
-18
lines changed

src/backend/utils/adt/float.c

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/utils/adt/float.c,v 1.138 2007/01/03 19:34:23 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/utils/adt/float.c,v 1.139 2007/01/03 22: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
*/
14461451
errno = 0;
14471452
result = pow(arg1, arg2);
1448-
if (errno == ERANGE || isnan(result))
1453+
if (errno == EDOM && isnan(result))
14491454
{
14501455
if ((fabs(arg1) > 1 && arg2 >= 0) || (fabs(arg1) < 1 && arg2 < 0))
14511456
result = (arg1 >= 0) ? get_float8_infinity() : -get_float8_infinity();
1452-
else
1457+
else if (fabs(arg1) != 1)
14531458
result = 0;
1459+
else
1460+
result = 1;
14541461
}
14551462

14561463
CHECKFLOATVAL(result, isinf(arg1) || isinf(arg2), arg1 == 0);
@@ -1467,20 +1474,7 @@ dexp(PG_FUNCTION_ARGS)
14671474
float8 arg1 = PG_GETARG_FLOAT8(0);
14681475
float8 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;
14761477
result = 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

14851479
CHECKFLOATVAL(result, isinf(arg1), false);
14861480
PG_RETURN_FLOAT8(result);

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy