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

Commitd6ec3d2

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 parent2acbeea commitd6ec3d2

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
@@ -1461,6 +1461,25 @@ dpow(PG_FUNCTION_ARGS)
14611461
float8arg2=PG_GETARG_FLOAT8(1);
14621462
float8result;
14631463

1464+
/*
1465+
* The POSIX spec says that NaN ^ 0 = 1, and 1 ^ NaN = 1, while all other
1466+
* cases with NaN inputs yield NaN (with no error). Many older platforms
1467+
* get one or more of these cases wrong, so deal with them via explicit
1468+
* logic rather than trusting pow(3).
1469+
*/
1470+
if (isnan(arg1))
1471+
{
1472+
if (isnan(arg2)||arg2!=0.0)
1473+
PG_RETURN_FLOAT8(get_float8_nan());
1474+
PG_RETURN_FLOAT8(1.0);
1475+
}
1476+
if (isnan(arg2))
1477+
{
1478+
if (arg1!=1.0)
1479+
PG_RETURN_FLOAT8(get_float8_nan());
1480+
PG_RETURN_FLOAT8(1.0);
1481+
}
1482+
14641483
/*
14651484
* The SQL spec requires that we emit a particular SQLSTATE error code for
14661485
* certain error conditions. Specifically, we don't return a
@@ -1482,12 +1501,11 @@ dpow(PG_FUNCTION_ARGS)
14821501
* and result == NaN for negative arg1 and very large arg2 (they must be
14831502
* using something different from our floor() test to decide it's
14841503
* invalid). Other platforms (HPPA) return errno == ERANGE and a large
1485-
* (HUGE_VAL) but finite result to signal overflow. Also, some versions
1486-
* of MSVC return errno == EDOM and result == NaN for NaN inputs.
1504+
* (HUGE_VAL) but finite result to signal overflow.
14871505
*/
14881506
errno=0;
14891507
result=pow(arg1,arg2);
1490-
if (errno==EDOM&&isnan(result)&& !isnan(arg1)&& !isnan(arg2))
1508+
if (errno==EDOM&&isnan(result))
14911509
{
14921510
if ((fabs(arg1)>1&&arg2 >=0)|| (fabs(arg1)<1&&arg2<0))
14931511
/* 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