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

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

From
Huong Dangminh
Date:
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 think it should be return 'NaN' in all of above cases.
I have tried to create a patch to fix it.
Please confirm the attached file.


---
Thanks and best regards,
Dang Minh Huong
NEC Solution Innovators, Ltd.
http://www.nec-solutioninnovators.co.jp/en/

Attachment

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

From
Euler Taveira
Date:
2018-04-10 5:30 GMT-03:00 Huong Dangminh <huo-dangminh@ys.jp.nec.com>:
> There are some cases that power() function does not work
> correctly with 'NaN' arguments in Windows environment.
> Something like,
>
What is your exact OS version? What is your postgres version? I tested
with Windows 10 (10.0.16299) x64 and couldn't reproduce the error.

> 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'.
>
Could you show us a simple test case? Print arguments, result and errno.


-- 
   Euler Taveira                                   Timbira -
http://www.timbira.com.br/
   PostgreSQL: Consultoria, Desenvolvimento, Suporte 24x7 e Treinamento


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

From
Euler Taveira
Date:
2018-04-10 5:30 GMT-03:00 Huong Dangminh <huo-dangminh@ys.jp.nec.com>:
> There are some cases that power() function does not work
> correctly with 'NaN' arguments in Windows environment.
> Something like,
>
What is your exact OS version? What is your postgres version? I tested
with Windows 10 (10.0.16299) x64 and couldn't reproduce the error.

> 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'.
>
Could you show us a simple test case? Print arguments, result and errno.


-- 
   Euler Taveira                                   Timbira -
http://www.timbira.com.br/
   PostgreSQL: Consultoria, Desenvolvimento, Suporte 24x7 e Treinamento


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

From
Huong Dangminh
Date:
Hi,
Thanks for response

# I will add this thread to current CF soon.

> 2018-04-10 5:30 GMT-03:00 Huong Dangminh <huo-dangminh@ys.jp.nec.com>:
> > There are some cases that power() function does not work correctly
> > with 'NaN' arguments in Windows environment.
> > Something like,
> >
> What is your exact OS version? What is your postgres version? I tested with
> Windows 10 (10.0.16299) x64 and couldn't reproduce the error.

I think it is not depended on OS version but the visual c++ runtime libraries version 
(It seem also be included in installers).

My environment:
====================================

- PostgreSQL: 9.6.8
  # I am using the EDB PostgreSQL Installer
  # It also can reproduce in PostgreSQL 10.3 or 9.5.12

  >postgres -V
  postgres (PostgreSQL) 9.6.8

  >psql -c "select version()"
                             version
  -------------------------------------------------------------
   PostgreSQL 9.6.8, compiled by Visual C++ build 1800, 64-bit
  (1 row)

  >psql -c "select 'NaN'^11"
  ERROR:  value out of range: underflow

- OS: Microsoft Windows 10 Pro 10.0.14393 build 14393

=============================

> > 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'.
> >
> Could you show us a simple test case? Print arguments, result and errno.

It just is my confirmation when debug PostgreSQL in Windows environment.
# I built PostgreSQL with VC++ 2012 in debug mode and confirmed.
I don't know how to print those values.


---
Thanks and best regards,
Dang Minh Huong
NEC Solution Innovators, Ltd.
http://www.nec-solutioninnovators.co.jp/en/

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

From
Huong Dangminh
Date:
Hi,
Thanks for response

# I will add this thread to current CF soon.

> 2018-04-10 5:30 GMT-03:00 Huong Dangminh <huo-dangminh@ys.jp.nec.com>:
> > There are some cases that power() function does not work correctly
> > with 'NaN' arguments in Windows environment.
> > Something like,
> >
> What is your exact OS version? What is your postgres version? I tested with
> Windows 10 (10.0.16299) x64 and couldn't reproduce the error.

I think it is not depended on OS version but the visual c++ runtime libraries version 
(It seem also be included in installers).

My environment:
====================================

- PostgreSQL: 9.6.8
  # I am using the EDB PostgreSQL Installer
  # It also can reproduce in PostgreSQL 10.3 or 9.5.12

  >postgres -V
  postgres (PostgreSQL) 9.6.8

  >psql -c "select version()"
                             version
  -------------------------------------------------------------
   PostgreSQL 9.6.8, compiled by Visual C++ build 1800, 64-bit
  (1 row)

  >psql -c "select 'NaN'^11"
  ERROR:  value out of range: underflow

- OS: Microsoft Windows 10 Pro 10.0.14393 build 14393

=============================

> > 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'.
> >
> Could you show us a simple test case? Print arguments, result and errno.

It just is my confirmation when debug PostgreSQL in Windows environment.
# I built PostgreSQL with VC++ 2012 in debug mode and confirmed.
I don't know how to print those values.


---
Thanks and best regards,
Dang Minh Huong
NEC Solution Innovators, Ltd.
http://www.nec-solutioninnovators.co.jp/en/

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

From
David Rowley
Date:
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


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

From
David Rowley
Date:
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


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

From
Euler Taveira
Date:
2018-04-11 0:13 GMT-03:00 David Rowley <david.rowley@2ndquadrant.com>:
> 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.
>
FWIW, I tested in MSVC 2017 (15.6.4) and it worked like expected.
Looking at [1], it seems there could be nasty bugs when using math
functions in MSVC < 2013 (or 2015). I don't have some older MSVC here
to try /fp:OPTIONHERE [2] to see if it makes any difference.


[1] https://docs.microsoft.com/en-us/cpp/porting/floating-point-migration-issues
[2] https://msdn.microsoft.com/pt-br/library/e7s85ffb.aspx


-- 
   Euler Taveira                                   Timbira -
http://www.timbira.com.br/
   PostgreSQL: Consultoria, Desenvolvimento, Suporte 24x7 e Treinamento


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

From
Euler Taveira
Date:
2018-04-11 0:13 GMT-03:00 David Rowley <david.rowley@2ndquadrant.com>:
> 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.
>
FWIW, I tested in MSVC 2017 (15.6.4) and it worked like expected.
Looking at [1], it seems there could be nasty bugs when using math
functions in MSVC < 2013 (or 2015). I don't have some older MSVC here
to try /fp:OPTIONHERE [2] to see if it makes any difference.


[1] https://docs.microsoft.com/en-us/cpp/porting/floating-point-migration-issues
[2] https://msdn.microsoft.com/pt-br/library/e7s85ffb.aspx


-- 
   Euler Taveira                                   Timbira -
http://www.timbira.com.br/
   PostgreSQL: Consultoria, Desenvolvimento, Suporte 24x7 e Treinamento


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

From
Huong Dangminh
Date:
Thanks for confirming.
 
> 2018-04-11 0:13 GMT-03:00 David Rowley <david.rowley@2ndquadrant.com>:
> > 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.
> >
> FWIW, I tested in MSVC 2017 (15.6.4) and it worked like expected.
> Looking at [1], it seems there could be nasty bugs when using math functions
> in MSVC < 2013 (or 2015). I don't have some older MSVC here to try
> /fp:OPTIONHERE [2] to see if it makes any difference.

Thanks.
Anyway currently PostgreSQL installers seem not be compiled with MSVC 2017, 
so it should be fix for current users?
I updated the patch as David Rowley mentioned.


---
Thanks and best regards,
Dang Minh Huong
NEC Solution Innovators, Ltd.
http://www.nec-solutioninnovators.co.jp/en/


Attachment

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

From
Huong Dangminh
Date:
Thanks for confirming.
 
> 2018-04-11 0:13 GMT-03:00 David Rowley <david.rowley@2ndquadrant.com>:
> > 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.
> >
> FWIW, I tested in MSVC 2017 (15.6.4) and it worked like expected.
> Looking at [1], it seems there could be nasty bugs when using math functions
> in MSVC < 2013 (or 2015). I don't have some older MSVC here to try
> /fp:OPTIONHERE [2] to see if it makes any difference.

Thanks.
Anyway currently PostgreSQL installers seem not be compiled with MSVC 2017, 
so it should be fix for current users?
I updated the patch as David Rowley mentioned.


---
Thanks and best regards,
Dang Minh Huong
NEC Solution Innovators, Ltd.
http://www.nec-solutioninnovators.co.jp/en/


Attachment

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

From
David Rowley
Date:
On 11 April 2018 at 16:42, Huong Dangminh <huo-dangminh@ys.jp.nec.com> wrote:
> I updated the patch as David Rowley mentioned.

Looks fine to me. Please add to the next commitfest.

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


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

From
David Rowley
Date:
On 11 April 2018 at 16:42, Huong Dangminh <huo-dangminh@ys.jp.nec.com> wrote:
> I updated the patch as David Rowley mentioned.

Looks fine to me. Please add to the next commitfest.

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


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

From
Huong Dangminh
Date:
> > I updated the patch as David Rowley mentioned.
> 
> Looks fine to me. Please add to the next commitfest.

Thanks. Added.

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

---
Thanks and best regards,
Dang Minh Huong
NEC Solution Innovators, Ltd.
http://www.nec-solutioninnovators.co.jp/en/


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

From
Huong Dangminh
Date:
> > I updated the patch as David Rowley mentioned.
> 
> Looks fine to me. Please add to the next commitfest.

Thanks. Added.

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

---
Thanks and best regards,
Dang Minh Huong
NEC Solution Innovators, Ltd.
http://www.nec-solutioninnovators.co.jp/en/


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

From
Tom Lane
Date:
Huong Dangminh <huo-dangminh@ys.jp.nec.com> writes:
>> 2018-04-11 0:13 GMT-03:00 David Rowley <david.rowley@2ndquadrant.com>:
>>> 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.

> I updated the patch as David Rowley mentioned.

Pushed.  I'd mainly note that you need to update all the variant float8
expected-files, not just the primary one.  (Sometimes this requires a
bit of guesswork, but here we're expecting all platforms to produce
the same result.  The buildfarm should tell us if I got it wrong.)

            regards, tom lane


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

From
Tom Lane
Date:
Huong Dangminh <huo-dangminh@ys.jp.nec.com> writes:
>> 2018-04-11 0:13 GMT-03:00 David Rowley <david.rowley@2ndquadrant.com>:
>>> 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.

> I updated the patch as David Rowley mentioned.

Pushed.  I'd mainly note that you need to update all the variant float8
expected-files, not just the primary one.  (Sometimes this requires a
bit of guesswork, but here we're expecting all platforms to produce
the same result.  The buildfarm should tell us if I got it wrong.)

            regards, tom lane


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

From
David Rowley
Date:
On 30 April 2018 at 07:24, Tom Lane <tgl@sss.pgh.pa.us> wrote:
> Pushed.  I'd mainly note that you need to update all the variant float8
> expected-files, not just the primary one.  (Sometimes this requires a
> bit of guesswork, but here we're expecting all platforms to produce
> the same result.  The buildfarm should tell us if I got it wrong.)

gaur does not seem happy with this. I get the impression that pow(1,
NaN) and pow(NaN, 0) on that machine must be returning NaN and setting
errno to EDOM, and now that we're only using that code path when both
are are non-NaN we no longer hit the special case which does result =
1;

I wonder if it's better just to hard code these two cases before even
calling the pow() function.

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


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

From
David Rowley
Date:
On 30 April 2018 at 07:24, Tom Lane <tgl@sss.pgh.pa.us> wrote:
> Pushed.  I'd mainly note that you need to update all the variant float8
> expected-files, not just the primary one.  (Sometimes this requires a
> bit of guesswork, but here we're expecting all platforms to produce
> the same result.  The buildfarm should tell us if I got it wrong.)

gaur does not seem happy with this. I get the impression that pow(1,
NaN) and pow(NaN, 0) on that machine must be returning NaN and setting
errno to EDOM, and now that we're only using that code path when both
are are non-NaN we no longer hit the special case which does result =
1;

I wonder if it's better just to hard code these two cases before even
calling the pow() function.

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


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

From
Tom Lane
Date:
David Rowley <david.rowley@2ndquadrant.com> writes:
> I wonder if it's better just to hard code these two cases before even
> calling the pow() function.

Yeah, see my followup --- I also found out that SUSv2 (POSIX 1997)
doesn't require either of these special cases, which helps explain
why the inconsistency on older platforms.

Hacking on a patch now.

            regards, tom lane


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

From
Tom Lane
Date:
David Rowley <david.rowley@2ndquadrant.com> writes:
> I wonder if it's better just to hard code these two cases before even
> calling the pow() function.

Yeah, see my followup --- I also found out that SUSv2 (POSIX 1997)
doesn't require either of these special cases, which helps explain
why the inconsistency on older platforms.

Hacking on a patch now.

            regards, tom lane


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

From
Huong Dangminh
Date:
> From: Tom Lane [mailto:tgl@sss.pgh.pa.us]
> > I updated the patch as David Rowley mentioned.
>
> Pushed.  I'd mainly note that you need to update all the variant float8
> expected-files, not just the primary one.  (Sometimes this requires a bit

Thank you.
I will be careful next time.

> of guesswork, but here we're expecting all platforms to produce the same
> result.  The buildfarm should tell us if I got it wrong.)

Also thanks a lot of fixing failure in BSD platform as the result from buildfarm.


---
Thanks and best regards,
Dang Minh Huong
NEC Solution Innovators, Ltd.
http://www.nec-solutioninnovators.co.jp/en/



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

From
Huong Dangminh
Date:
> From: Tom Lane [mailto:tgl@sss.pgh.pa.us]
> > I updated the patch as David Rowley mentioned.
>
> Pushed.  I'd mainly note that you need to update all the variant float8
> expected-files, not just the primary one.  (Sometimes this requires a bit

Thank you.
I will be careful next time.

> of guesswork, but here we're expecting all platforms to produce the same
> result.  The buildfarm should tell us if I got it wrong.)

Also thanks a lot of fixing failure in BSD platform as the result from buildfarm.


---
Thanks and best regards,
Dang Minh Huong
NEC Solution Innovators, Ltd.
http://www.nec-solutioninnovators.co.jp/en/