Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit5674eb9

Browse files
committed
Fix power() for large inputs yet more.
Buildfarm results for commite532b1d reveal the error in my thinkingabout the unexpected-EDOM case. I'd supposed this was no longer reallya live issue, but it seems the fix for glibc's bug #3866 is not all thatold, and we still have at least one buildfarm animal (lapwing) with thebug. Hence, resurrect essentially the previous logic (but, I hope, lessopaquely presented), and explain what it is we're really doing here.Also, blindly try to fix fossa's failure by tweaking the logic thatfigures out whether y is an odd integer when x is -inf. This smellsa whole lot like a compiler bug, but I lack access to icc to try topin it down. Maybe doing division instead of multiplication willdodge the issue.Discussion:https://postgr.es/m/E1jkU7H-00024V-NZ@gemulon.postgresql.org
1 parent2961c97 commit5674eb9

File tree

1 file changed

+23
-11
lines changed

1 file changed

+23
-11
lines changed

‎src/backend/utils/adt/float.c

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1583,7 +1583,7 @@ dpow(PG_FUNCTION_ARGS)
15831583
if (arg2==floor(arg2))
15841584
{
15851585
/* y is integral; it's odd if y/2 is not integral */
1586-
doublehalfy=arg2*0.5;/* should be computed exactly */
1586+
doublehalfy=arg2/2;/* should be computed exactly */
15871587

15881588
if (halfy!=floor(halfy))
15891589
yisoddinteger= true;
@@ -1608,17 +1608,29 @@ dpow(PG_FUNCTION_ARGS)
16081608
if (errno==EDOM||isnan(result))
16091609
{
16101610
/*
1611-
* We eliminated all the possible domain errors above, or should
1612-
* have; but if pow() has a more restrictive test for "is y an
1613-
* integer?" than we do, we could get here anyway. Historical
1614-
* evidence suggests that some platforms once implemented the test
1615-
* as "y == (long) y", which of course misbehaves beyond LONG_MAX.
1616-
* There's not a lot of choice except to accept the platform's
1617-
* conclusion that we have a domain error.
1611+
* We handled all possible domain errors above, so this should be
1612+
* impossible. However, old glibc versions on x86 have a bug that
1613+
* causes them to fail this way for abs(y) greater than 2^63:
1614+
*
1615+
* https://sourceware.org/bugzilla/show_bug.cgi?id=3866
1616+
*
1617+
* Hence, if we get here, assume y is finite but large (large
1618+
* enough to be certainly even). The result should be 0 if x == 0,
1619+
* 1.0 if abs(x) == 1.0, otherwise an overflow or underflow error.
16181620
*/
1619-
ereport(ERROR,
1620-
(errcode(ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION),
1621-
errmsg("a negative number raised to a non-integer power yields a complex result")));
1621+
if (arg1==0.0)
1622+
result=0.0;/* we already verified y is positive */
1623+
else
1624+
{
1625+
doubleabsx=fabs(arg1);
1626+
1627+
if (absx==1.0)
1628+
result=1.0;
1629+
elseif (arg2 >=0.0 ? (absx>1.0) : (absx<1.0))
1630+
float_overflow_error();
1631+
else
1632+
float_underflow_error();
1633+
}
16221634
}
16231635
elseif (errno==ERANGE)
16241636
{

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp