[Bug c++/57034] ternary operator with float infinity in O0
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57034 --- Comment #4 from Christopher Hite christopher.hite at jpmorgan dot com 2013-04-23 11:35:25 UTC --- 64-bit. Thanks for pointing out I was converting to float and back. Both of the following work: int32_t z3=(qFuture = double(MAX) ? MAX : double(qFuture) ); //works int32_t z4=(qFuture = double(MAX) ? MAX : int32_t(qFuture) ); // works The following also works: int32_t z5=(qFuture = MAX ? MAX : int32_t(qFuture) ); //works which seems to contradict what you were saying that if the integral value can't be perfectly represented by the float it fails. const float fMAX=std::numeric_limitsint32_t::max(); (gdb) fMAX = 2.14748365e+09 Is this bad code? Should I convert to double before float? What about larger ints? All I'm tring to do is convert float to int clipping at max int. What's the best way to do it? Can I calculate the highest float that is convertible to an int? Or do I have to check that the conversion fails.
[Bug c++/57034] ternary operator with float infinity in O0
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57034 --- Comment #5 from Jakub Jelinek jakub at gcc dot gnu.org 2013-04-23 11:59:35 UTC --- Guess you should read something about floating point. 0x7fff of course can't be represented exactly in IEEE 754 single precision format, so when you convert 2147483647 to float, you get 2147483648.0f (1 higher than that), and that doesn't fit into int range, so [conv.fpint]/1 applies and it is undefined behavior. IEEE 754 double precision format has bigger mantissa, so if you convert 2147483647 to double, you get 2147483647.0 and can convert it back to int, but if you try the same with long long maximum, it won't work again.
[Bug c++/57034] ternary operator with float infinity in O0
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57034 --- Comment #6 from Christopher Hite christopher.hite at jpmorgan dot com 2013-04-23 17:26:26 UTC --- Good, I was a big worried I couldn't convert ints to floats unless the int was safely mappable. It rounds which is what I'd expect. I now think z5 is safe, since int32_t(float(MAX)) wouldn't be evaluated. const float fMAX=std::numeric_limitsint32_t::max(); Any (positive) float less than fMax, must be representable in int32_t, though z5 will never equal MAX-1 or MAX-2 Do you agree? z5 is definately clearer code than playing with fetestexcept(). I'd guess it's also faster.
[Bug c++/57034] ternary operator with float infinity in O0
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57034 --- Comment #7 from Jakub Jelinek jakub at gcc dot gnu.org 2013-04-23 17:42:25 UTC --- GCC bugzilla is a bug reporting mechanism, not a C++ discussion forum, so better follow-up elsewhere. That said, yes, if qFuture isn't negative and is smaller than INT_MAX converted to float (aka 2147483648.0f), then it will convert fine from float to int and will be smaller than INT_MAX.
[Bug c++/57034] ternary operator with float infinity in O0
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57034 --- Comment #1 from Christopher Hite christopher.hite at jpmorgan dot com 2013-04-22 17:36:52 UTC --- Created attachment 29915 -- http://gcc.gnu.org/bugzilla/attachment.cgi?id=29915 unit test of bug + build instructions in comment
[Bug c++/57034] ternary operator with float infinity in O0
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57034 --- Comment #2 from Andrew Pinski pinskia at gcc dot gnu.org 2013-04-22 18:20:45 UTC --- Is this on i686 (32bit)?
[Bug c++/57034] ternary operator with float infinity in O0
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57034 Jakub Jelinek jakub at gcc dot gnu.org changed: What|Removed |Added Status|UNCONFIRMED |RESOLVED CC||jakub at gcc dot gnu.org Resolution||INVALID --- Comment #3 from Jakub Jelinek jakub at gcc dot gnu.org 2013-04-22 19:07:25 UTC --- Why do you think it is a bug? As one arm of the ?: has float type, both arms need to be converted to float, and INT_MAX isn't representable in float, you don't have to get the same value back. With optimizations it might be evaluated in extended precision and on i?86 0x7fff fits into long double, but e.g. on x86_64 you'll always get 0x8000.