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

Commit6bdf130

Browse files
committed
Avoid wrong results for power() with NaN input on more platforms.
Buildfarm results show that the modern POSIX rule that 1 ^ NaN = 1 is nothonored on *BSD until relatively recently, and really old platforms don'tbelieve that NaN ^ 0 = 1 either. (This is unsurprising, perhaps, sinceSUSv2 doesn't require either behavior.) In hopes of getting to platformindependent behavior, let's deal with all the NaN-input cases explicitlyin dpow().Note that numeric_power() doesn't know either of these special cases.But since that behavior is platform-independent, I think it should beaddressed separately, and probably not back-patched.Discussion:https://postgr.es/m/75DB81BEEA95B445AE6D576A0A5C9E936A73E741@BPXM05GP.gisp.nec.co.jp
1 parent68e7e97 commit6bdf130

File tree

6 files changed

+46
-3
lines changed

6 files changed

+46
-3
lines changed

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

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1548,6 +1548,25 @@ dpow(PG_FUNCTION_ARGS)
15481548
float8arg2=PG_GETARG_FLOAT8(1);
15491549
float8result;
15501550

1551+
/*
1552+
* The POSIX spec says that NaN ^ 0 = 1, and 1 ^ NaN = 1, while all other
1553+
* cases with NaN inputs yield NaN (with no error). Many older platforms
1554+
* get one or more of these cases wrong, so deal with them via explicit
1555+
* logic rather than trusting pow(3).
1556+
*/
1557+
if (isnan(arg1))
1558+
{
1559+
if (isnan(arg2)||arg2!=0.0)
1560+
PG_RETURN_FLOAT8(get_float8_nan());
1561+
PG_RETURN_FLOAT8(1.0);
1562+
}
1563+
if (isnan(arg2))
1564+
{
1565+
if (arg1!=1.0)
1566+
PG_RETURN_FLOAT8(get_float8_nan());
1567+
PG_RETURN_FLOAT8(1.0);
1568+
}
1569+
15511570
/*
15521571
* The SQL spec requires that we emit a particular SQLSTATE error code for
15531572
* certain error conditions. Specifically, we don't return a
@@ -1569,12 +1588,11 @@ dpow(PG_FUNCTION_ARGS)
15691588
* and result == NaN for negative arg1 and very large arg2 (they must be
15701589
* using something different from our floor() test to decide it's
15711590
* invalid). Other platforms (HPPA) return errno == ERANGE and a large
1572-
* (HUGE_VAL) but finite result to signal overflow. Also, some versions
1573-
* of MSVC return errno == EDOM and result == NaN for NaN inputs.
1591+
* (HUGE_VAL) but finite result to signal overflow.
15741592
*/
15751593
errno=0;
15761594
result=pow(arg1,arg2);
1577-
if (errno==EDOM&&isnan(result)&& !isnan(arg1)&& !isnan(arg2))
1595+
if (errno==EDOM&&isnan(result))
15781596
{
15791597
if ((fabs(arg1)>1&&arg2 >=0)|| (fabs(arg1)<1&&arg2<0))
15801598
/* The sign of Inf is not significant in this case. */

‎src/test/regress/expected/float8-exp-three-digits-win32.out

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,12 @@ SELECT power(float8 'NaN', float8 'NaN');
358358
NaN
359359
(1 row)
360360

361+
SELECT power(float8 '-1', float8 'NaN');
362+
power
363+
-------
364+
NaN
365+
(1 row)
366+
361367
SELECT power(float8 '1', float8 'NaN');
362368
power
363369
-------

‎src/test/regress/expected/float8-small-is-zero.out

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,12 @@ SELECT power(float8 'NaN', float8 'NaN');
362362
NaN
363363
(1 row)
364364

365+
SELECT power(float8 '-1', float8 'NaN');
366+
power
367+
-------
368+
NaN
369+
(1 row)
370+
365371
SELECT power(float8 '1', float8 'NaN');
366372
power
367373
-------

‎src/test/regress/expected/float8-small-is-zero_1.out

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,12 @@ SELECT power(float8 'NaN', float8 'NaN');
362362
NaN
363363
(1 row)
364364

365+
SELECT power(float8 '-1', float8 'NaN');
366+
power
367+
-------
368+
NaN
369+
(1 row)
370+
365371
SELECT power(float8 '1', float8 'NaN');
366372
power
367373
-------

‎src/test/regress/expected/float8.out

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,12 @@ SELECT power(float8 'NaN', float8 'NaN');
358358
NaN
359359
(1 row)
360360

361+
SELECT power(float8 '-1', float8 'NaN');
362+
power
363+
-------
364+
NaN
365+
(1 row)
366+
361367
SELECT power(float8 '1', float8 'NaN');
362368
power
363369
-------

‎src/test/regress/sql/float8.sql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ SELECT power(float8 '144', float8 '0.5');
111111
SELECT power(float8'NaN', float8'0.5');
112112
SELECT power(float8'144', float8'NaN');
113113
SELECT power(float8'NaN', float8'NaN');
114+
SELECT power(float8'-1', float8'NaN');
114115
SELECT power(float8'1', float8'NaN');
115116
SELECT power(float8'NaN', float8'0');
116117

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp