[math] boost::math::isfinite fails with --fast-math

Hi all, I'm wandering if this is to be expected, the following code fails if compiled with --fast-math: //==================================================== #include <boost/math/special_functions/fpclassify.hpp> int main() { const float a = 0.0f/0.0f; assert(not boost::math::isfinite(a)); } //==================================================== Regards Gaetano Mendola

I'm wandering if this is to be expected, the following code fails if compiled with --fast-math:
//==================================================== #include <boost/math/special_functions/fpclassify.hpp> int main() { const float a = 0.0f/0.0f; assert(not boost::math::isfinite(a)); }
yes: --ffast-math enables -ffinite-math-only, which (man gcc):
Allow optimizations for floating-point arithmetic that assume that arguments and results are not NaNs or +-Infs.

-----Original Message----- From: boost-bounces@lists.boost.org [mailto:boost-bounces@lists.boost.org] On Behalf Of Gaetano Mendola Sent: Monday, November 26, 2012 12:12 PM To: boost@lists.boost.org Subject: [boost] [math] boost::math::isfinite fails with --fast-math
Hi all, I'm wandering if this is to be expected, the following code fails if compiled with --fast-math:
//==================================================== #include <boost/math/special_functions/fpclassify.hpp> int main() { const float a = 0.0f/0.0f; assert(not boost::math::isfinite(a)); } //====================================================
http://gcc.gnu.org/onlinedocs/gcc-4.1.1/gcc/Optimize-Options.html says " -ffast-math Sets -fno-math-errno, -funsafe-math-optimizations, -fno-trapping-math, -ffinite-math-only, <<<<<<<<<<<< so the IEEE pattern for infinity will never be set. -fno-rounding-math, -fno-signaling-nans and fcx-limited-range. This option causes the preprocessor macro __FAST_MATH__ to be defined. " So I fear that all bets are off as soon as you enable this option. (and anyway const float a = 0.0f/0.0f; will be optimised away). And dividing by zero is never a good idea ;-) But see what the organ grinder has to say... Paul --- Paul A. Bristow, Prizet Farmhouse, Kendal LA8 8AB UK +44 1539 561830 07714330204 pbristow@hetp.u-net.com

On 11/26/2012 01:29 PM, Paul A. Bristow wrote:
http://gcc.gnu.org/onlinedocs/gcc-4.1.1/gcc/Optimize-Options.html
says
" -ffast-math Sets -fno-math-errno, -funsafe-math-optimizations, -fno-trapping-math,
-ffinite-math-only, <<<<<<<<<<<< so the IEEE pattern for infinity will never be set.
-fno-rounding-math, -fno-signaling-nans and fcx-limited-range.
This option causes the preprocessor macro __FAST_MATH__ to be defined.
"
So I fear that all bets are off as soon as you enable this option.
(and anyway const float a = 0.0f/0.0f; will be optimised away).
And dividing by zero is never a good idea ;-)
That was the fastest way I found to get a nan I would have written: const float a = std::numeric_limits<float>::quiet_NaN(); obtaining the same effect. Gaetano

I'm wandering if this is to be expected, the following code fails if compiled with --fast-math:
//==================================================== #include <boost/math/special_functions/fpclassify.hpp> int main() { const float a = 0.0f/0.0f; assert(not boost::math::isfinite(a)); }
Which fails - does the 0/0 actually yield an infinity? Or is it isfinite that fails? Either way is hard to make guarentees once you enable an option like that. John.

On 11/26/2012 02:13 PM, John Maddock wrote:
I'm wandering if this is to be expected, the following code fails if compiled with --fast-math:
//==================================================== #include <boost/math/special_functions/fpclassify.hpp> int main() { const float a = 0.0f/0.0f; assert(not boost::math::isfinite(a)); }
Which fails - does the 0/0 actually yield an infinity? Or is it isfinite that fails?
Either way is hard to make guarentees once you enable an option like that.
The following code: #include <boost/math/special_functions/fpclassify.hpp> int main() { const float a = 0.0f/0.0f; std::cout << "a => " << a << std::endl; std::cout << "boost::math::isfinite(a) => " << boost::math::isfinite(a) << std::endl; std::cout << "a != a: " << (a!=a ? "true" : "false") << std::endl; } gives: a => nan boost::math::isfinite(a) => 1 a != a: true so I believe somehow even with --fast-math it should be possible to make it "working" (if it has to be). Gaetano

I'm wandering if this is to be expected, the following code fails if compiled with --fast-math:
//==================================================== #include <boost/math/special_functions/fpclassify.hpp> int main() { const float a = 0.0f/0.0f; assert(not boost::math::isfinite(a)); }
Which fails - does the 0/0 actually yield an infinity? Or is it isfinite that fails?
Either way is hard to make guarentees once you enable an option like that.
The following code:
[snip]
so I believe somehow even with --fast-math it should be possible to make it "working" (if it has to be).
rtfm: you asked the compiler to assume that neither arguments nor results are NaNs or Infs. if your code uses or generates NaNs or Infs its behavior is undefined.

On 11/26/2012 02:42 PM, Tim Blechmann wrote:
I'm wandering if this is to be expected, the following code fails if compiled with --fast-math:
//==================================================== #include <boost/math/special_functions/fpclassify.hpp> int main() { const float a = 0.0f/0.0f; assert(not boost::math::isfinite(a)); }
Which fails - does the 0/0 actually yield an infinity? Or is it isfinite that fails?
Either way is hard to make guarentees once you enable an option like that.
The following code:
[snip]
so I believe somehow even with --fast-math it should be possible to make it "working" (if it has to be).
rtfm: you asked the compiler to assume that neither arguments nor results are NaNs or Infs. if your code uses or generates NaNs or Infs its behavior is undefined.
rtfp (p = post): I'm saying that "if it has to be fixed" somehow boost::math::isfinite can still detect if a float has a "nan" configuration I was even asking if that was expected behavior by "boost::math::isfinite" or not. If boost::math::isfinite has to be "compatible" with ::isfinite() then yes it's normal, this can be specified in the boost documentation. Gaetano

On 2012-11-26 15:07, Gaetano Mendola wrote:
On 11/26/2012 02:42 PM, Tim Blechmann wrote:
I'm wandering if this is to be expected, the following code fails if compiled with --fast-math:
//==================================================== #include <boost/math/special_functions/fpclassify.hpp> int main() { const float a = 0.0f/0.0f; assert(not boost::math::isfinite(a)); }
Which fails - does the 0/0 actually yield an infinity? Or is it isfinite that fails?
Either way is hard to make guarentees once you enable an option like that.
The following code:
[snip]
so I believe somehow even with --fast-math it should be possible to make it "working" (if it has to be).
rtfm: you asked the compiler to assume that neither arguments nor results are NaNs or Infs. if your code uses or generates NaNs or Infs its behavior is undefined.
rtfp (p = post): I'm saying that "if it has to be fixed" somehow boost::math::isfinite can still detect if a float has a "nan" configuration I was even asking if that was expected behavior by "boost::math::isfinite" or not.
If boost::math::isfinite has to be "compatible" with ::isfinite() then yes it's normal, this can be specified in the boost documentation.
Gaetano
Interesting as this may be, I am receiving all your mails twice (maybe a result of sending a copy to gmane.comp.lib.boost.devel?). Can you please try to change your settings? Thanks and regards, Roland

On 11/26/2012 03:37 PM, Roland Bock wrote:
On 2012-11-26 15:07, Gaetano Mendola wrote:
On 11/26/2012 02:42 PM, Tim Blechmann wrote:
I'm wandering if this is to be expected, the following code fails if compiled with --fast-math:
//==================================================== #include <boost/math/special_functions/fpclassify.hpp> int main() { const float a = 0.0f/0.0f; assert(not boost::math::isfinite(a)); }
Which fails - does the 0/0 actually yield an infinity? Or is it isfinite that fails?
Either way is hard to make guarentees once you enable an option like that.
The following code:
[snip]
so I believe somehow even with --fast-math it should be possible to make it "working" (if it has to be).
rtfm: you asked the compiler to assume that neither arguments nor results are NaNs or Infs. if your code uses or generates NaNs or Infs its behavior is undefined.
rtfp (p = post): I'm saying that "if it has to be fixed" somehow boost::math::isfinite can still detect if a float has a "nan" configuration I was even asking if that was expected behavior by "boost::math::isfinite" or not.
If boost::math::isfinite has to be "compatible" with ::isfinite() then yes it's normal, this can be specified in the boost documentation.
Gaetano
Interesting as this may be, I am receiving all your mails twice (maybe a result of sending a copy to gmane.comp.lib.boost.devel?). Can you please try to change your settings?
Ops sorry, you are right, replying to all has that effect, thank you for pointing it out. Gaetano

-----Original Message----- From: boost-bounces@lists.boost.org [mailto:boost-bounces@lists.boost.org] On Behalf Of Gaetano Mendola Sent: Monday, November 26, 2012 1:34 PM To: boost@lists.boost.org Cc: John Maddock Subject: Re: [boost] [math] boost::math::isfinite fails with --fast-math
On 11/26/2012 02:13 PM, John Maddock wrote:
I'm wandering if this is to be expected, the following code fails if compiled with --fast-math:
//==================================================== #include <boost/math/special_functions/fpclassify.hpp> int main() { const float a = 0.0f/0.0f; assert(not boost::math::isfinite(a)); }
Which fails - does the 0/0 actually yield an infinity? Or is it isfinite that fails?
Either way is hard to make guarentees once you enable an option like that.
The following code:
#include <boost/math/special_functions/fpclassify.hpp> int main() { const float a = 0.0f/0.0f; std::cout << "a => " << a << std::endl; std::cout << "boost::math::isfinite(a) => " << boost::math::isfinite(a) << std::endl; std::cout << "a != a: " << (a!=a ? "true" : "false") << std::endl; }
gives:
a => nan boost::math::isfinite(a) => 1 a != a: true
This appears to perhaps not conform to this -ffinite-math-only, <<<<<<<<<<<< so the IEEE pattern for infinity (or NaN?) will never be set. " -ffast-math Sets -fno-math-errno, -funsafe-math-optimizations, -fno-trapping-math, -ffinite-math-only, <<<<<<<<<<<< so the IEEE pattern for infinity will never be set. -fno-rounding-math, -fno-signaling-nans Or does this mean quiet NaNs *are* supported? And do the specific tests boost::math:: isnan and isinf help you any more? (They shouldn't, I think). Can you achieve what you want (-funsafe-math-optimizations for speed ?) by specifying individual options? And provide some test cases and raise a Trac ticket (No promises - the logic is more than byzantine enough already). Paul

-----Original Message----- From: boost-bounces@lists.boost.org [mailto:boost-bounces@lists.boost.org] On Behalf Of Tim Blechmann Sent: Monday, November 26, 2012 4:31 PM To: boost@lists.boost.org Subject: Re: [boost] [math] boost::math::isfinite fails with --fast-math
Which fails - does the 0/0 actually yield an infinity? Or is it isfinite
that fails? 0/0 should yield NaN, not infinity.
0/0 can yield anything, if -ffast-math is passed as compile flag ...
You are both right - sorry I got my infinite and infinity mis-typed. -ffinite-math-only, <<<<<<<<<<<< so the IEEE pattern for infinity will never be set. -fno-signaling-nans <<<<<<<<<<<< so the IEEE pattern for signalling will never be set. (-ffast-math sets a whole group of options, including these). But it appears from Gaetano's tests that the (or a) pattern for *quiet_NaN is set*. So I would expect that isnan might work. But I agree with John that this is a dodgy ill-defined area. Paul --- Paul A. Bristow, Prizet Farmhouse, Kendal LA8 8AB UK +44 1539 561830 07714330204 pbristow@hetp.u-net.com
participants (6)
-
Bjorn Reese
-
Gaetano Mendola
-
John Maddock
-
Paul A. Bristow
-
Roland Bock
-
Tim Blechmann