Re: power() function in Windows: "value out of range: underflow"

Поиск
Список
Период
Сортировка
От David Rowley
Тема Re: power() function in Windows: "value out of range: underflow"
Дата
Msg-id CAKJS1f9y5RqPps4i+13k9ry9pHZ2p_pCtZrOke0-4Nkz3POqbg@mail.gmail.com
обсуждение исходный текст
Ответ на power() function in Windows: "value out of range: underflow"  (Huong Dangminh <huo-dangminh@ys.jp.nec.com>)
Ответы Re: power() function in Windows: "value out of range: underflow"  (Euler Taveira <euler@timbira.com.br>)
Re: power() function in Windows: "value out of range: underflow"  (Euler Taveira <euler@timbira.com.br>)
Список pgsql-bugs
On 10 April 2018 at 20:30, Huong Dangminh <huo-dangminh@ys.jp.nec.com> wrote:
> Hi,
>
> There are some cases that power() function does not work
> correctly with 'NaN' arguments in Windows environment.
> Something like,
>
> postgres=# select power('NaN',11);
> ERROR:  value out of range: underflow
> postgres=# select power('NaN','NaN');
> ERROR:  value out of range: underflow
> postgres=# select power(11,'NaN');
> ERROR:  value out of range: underflow
>
> In Linux environment, instead of ERROR it returns 'NaN'.
>
> The reason here is,
> When pow() in float.c:dpow() is called with 'NaN' arguments,
> pow() returns 'NaN' but in Windows environment errno is set to
> EDOM(invalid floating-point exception).
> So, PostgreSQL update "result" and cause an ERROR in CHECKFLOATVAL macro.

I can recreate this when building with MSVC 2012. I confirm that I see
the same as you. Microsoft are setting errno to EDOM in the above 3
cases, where in Linux the result is still NaN, just the errno is not
set.

Looking at [1], it says:

* If x or y is a NaN, a NaN shall be returned (unless specified
elsewhere in this description).

* For any value of y (including NaN), if x is +1, 1.0 shall be returned.

* For any value of x (including NaN), if y is ±0, 1.0 shall be returned.

Which Microsoft seem to not have broken, they're just also setting the
errno to EDOM in the first case, which seems a little strange, but the
standard there does not seem to mention that it shouldn't do that.

You patch fixes the problem for me, and importantly the two following
cases still work:

postgres=# select power(1,'NaN');
 power
-------
     1
(1 row)


postgres=# select power('NaN', 0);
 power
-------
     1
(1 row)


There's no mention in the SQL standard about NaN handling in the above
two cases, but I wonder if it's worth also adding a couple of tests
for the above two cases to ensure all platforms are doing the same
thing... ?

I'd also rather see this line:

if (errno == EDOM && isnan(result) && !(isnan(arg1) || isnan(arg2)))

written as:

if (errno == EDOM && isnan(result) && !isnan(arg1) && !isnan(arg2))

[1] http://pubs.opengroup.org/onlinepubs/9699919799/functions/pow.html

--
 David Rowley                   http://www.2ndQuadrant.com/
 PostgreSQL Development, 24x7 Support, Training & Services


В списке pgsql-bugs по дате отправления:

Предыдущее
От: Soni M
Дата:
Сообщение: Re: pg_dump with disable trigger
Следующее
От: Michael Paquier
Дата:
Сообщение: Re: BUG #15105: OpenTransientFile() should be paired withCloseTransientFile() rather than close()