[endian] Testing floating point interoperability
On Fri, Jan 30, 2015 at 5:25 AM, Paul A. Bristow
* Anything else that you can think of to improve FP support.
The proof of the pudding is in the eating.
I'd suggest that *testing interoperability* is the key precaution that you should advise.
I'm starting to write a caution to go in the release, and will make that point. A new test, "floating_point_test", has been added to the endian test suite. It will focus on interoperability. (I know that you are talking about users testing their application needs, but I want to test Boost.Endian to be able to warn users of areas where there are known issues.)
It should obviously be between all possible combinations of processor hardware types.
It isn't just processor types. std::numeric_limits<float>::signaling_NaN() representation is 0x7fc00001 for Microsoft/Dinkumware, but is 0x7fa00000 for gcc and clang:-(
The test should include a range of floating-point values from min to max, and include NaN and infinity unless it is certain that they will never occur.
To get started, floating_point_test.cpp is testing float and double: numeric_limits<>::min() numeric_limits<>::max() numeric_limits<>::lowest() numeric_limits<>::epsilon() numeric_limits<>::round_error() numeric_limits<>::infinity() -numeric_limits<>::infinity() numeric_limits<>::quiet_NaN() numeric_limits<>::denorm_min() 0.0 -0.0 1.0 -1.0 native uint32_t 0x12345678U as a float native uint64_t 0x0123456789abcdefULL as a double pi<>() Are there other specific values worth testing?> (Unless very special precautions are taken, then infinity and NaN are like to rear their ugly heads
at some time - probably when you least want to see them!)
It must be possible to 'round-trip' all floating-point values.
That's one of the tests performed on each value.
You can't test all possible values (except for 32-bit float - 64-bit double takes about 50 years at current processor speeds ;-) but you can chose values (floating-point bit patterns) at random for a test lasting some minutes or even hours.
Could you provide the random number generation and otherwise help with this? I've only ever used integer RNGs. Thanks, --Beman
AMDG On 03/18/2015 07:24 AM, Beman Dawes wrote:
On Fri, Jan 30, 2015 at 5:25 AM, Paul A. Bristow
wrote: You can't test all possible values (except for 32-bit float - 64-bit double takes about 50 years at current processor speeds ;-) but you can chose values (floating-point bit patterns) at random for a test lasting some minutes or even hours.
Could you provide the random number generation and otherwise help with this? I've only ever used integer RNGs.
Since you want to test random bit patterns, the easiest way is to generate a 64-bit integer and memcpy it to a double. In Christ, Steven Watanabe
-----Original Message----- From: Boost [mailto:boost-bounces@lists.boost.org] On Behalf Of Steven Watanabe Sent: 18 March 2015 15:20 To: boost@lists.boost.org Subject: Re: [boost] [endian] Testing floating point interoperability
AMDG
On 03/18/2015 07:24 AM, Beman Dawes wrote:
On Fri, Jan 30, 2015 at 5:25 AM, Paul A. Bristow
wrote: You can't test all possible values (except for 32-bit float - 64-bit double takes about 50 years at current processor speeds ;-) but you can chose values (floating-point bit patterns) at random for a test lasting some minutes or even hours.
Could you provide the random number generation and otherwise help with this? I've only ever used integer RNGs.
Since you want to test random bit patterns, the easiest way is to generate a 64-bit integer and memcpy it to a double.
I'm not sure if it will prove realistic to test all the possible NaN patterns provided by IEEE
floating-point layout?
I would expect only those 'funny numbers' in std::numeric_limits to work
numeric_limits<>::infinity()
-numeric_limits<>::infinity()
numeric_limits<>::quiet_NaN()
perhaps (despite its meaninglessness) even
-numeric_limits<>::quiet_NaN()
There was some discussion about removing signaling_NaN
std::numeric_limits<float>::signaling_NaN() representation is
0x7fc00001 for Microsoft/Dinkumware, but is 0x7fa00000 for gcc and clang:-(
I would simply accept and document that signaling_NaN won't work (unless it does ;-)?
But if all of the tests prove to work, then fine.
If not, then in our round-trip testing John and I just tested for 'funny' with
#include
An exhaustive return-by-value round-trip test of all 4 billion possible bit patterns for float (but not double) has been run on Windows with the GCC and Microsoft compilers. For both compilers in release mode, and for GCC in debug mode, all bit patterns pass. But for Microsoft in debug mode, certain bit patterns do not round-trip correctly. For example, 7f810000 becomes 7fc10000. (Those are little endian representations). So what should Boost.Endian do? There is less than two weeks left before 1.58.0 ships, and even if this turns out to be a bug in the Microsoft compiler, it is likely to cause user problems. The most conservative approach is to remove the return-by-value reverse functions, and note in the docs that only in-place reverse is available for FP. That will give us more time to determine if return-by-value endianness reverse is valid for floating point. Opinions? --Beman
[Beman Dawes]
An exhaustive return-by-value round-trip test of all 4 billion possible bit patterns for float (but not double) has been run on Windows with the GCC and Microsoft compilers. For both compilers in release mode, and for GCC in debug mode, all bit patterns pass. But for Microsoft in debug mode, certain bit patterns do not round-trip correctly. For example, 7f810000 becomes 7fc10000. (Those are little endian representations).
I'll file a bug if you can give me a self-contained repro. Just one offending bit pattern is fine. Ideally, a repro that doesn't drag in Boost would be the easiest for the compiler team to investigate (i.e. if you can reduce it all the way down to standalone functions). STL
Beman Dawes wrote:
The most conservative approach is to remove the return-by-value reverse functions, and note in the docs that only in-place reverse is available for FP. That will give us more time to determine if return-by-value endianness reverse is valid for floating point.
Even if everything round-trips correctly on all compilers we care about, returning "wrong endianness" by value is not standard conforming for any type, not just float. int, for instance, is allowed to have padding bits and trap representations, or to not preserve the sign bit of negative zero.
On Fri, Mar 20, 2015 at 11:43 AM, Peter Dimov
Beman Dawes wrote:
The most conservative approach is to remove the return-by-value reverse functions, and note in the docs that only in-place reverse is available for FP. That will give us more time to determine if return-by-value endianness reverse is valid for floating point.
Even if everything round-trips correctly on all compilers we care about, returning "wrong endianness" by value is not standard conforming for any type, not just float. int, for instance, is allowed to have padding bits and trap representations, or to not preserve the sign bit of negative zero.
Understood. While that's a particular concern for floating point types, you are correct that it also applies to integer types even though two's complement integers have become ubiquitous. See my reply below to Rob Stewart for the impact on a 1.58.0 release. Thanks, --Beman
-----Original Message----- From: Boost [mailto:boost-bounces@lists.boost.org] On Behalf Of Beman Dawes Sent: 20 March 2015 13:40 To: Boost Developers List Subject: Re: [boost] [endian] Testing floating point interoperability
An exhaustive return-by-value round-trip test of all 4 billion possible bit patterns for float (but not double) has been run on Windows with the GCC and Microsoft compilers.
For both compilers in release mode, and for GCC in debug mode, all bit patterns pass.
But for Microsoft in debug mode, certain bit patterns do not round-trip correctly. For example, 7f810000 becomes 7fc10000. (Those are little endian representations).
So what should Boost.Endian do? There is less than two weeks left before 1.58.0 ships, and even if this turns out to be a bug in the Microsoft compiler, it is likely to cause user problems.
The most conservative approach is to remove the return-by-value reverse functions, and note in the docs that only in-place reverse is available for FP. That will give us more time to determine if return-by-value endianness reverse is valid for floating point.
Opinions?
I'm not sure. This looks like a NaN? As I said before, I'd explicitly not make promises for any NaN except std::numeric_limits<>::quiet_NaN (not even the deprecated signalling_NaN) Anyone using another NaN is likely to be not portable and not expecting Boost to be portable anyway? But Peter Dimov's objection may be more significant. Paul --- Paul A. Bristow Prizet Farmhouse Kendal UK LA8 8AB +44 (0) 1539 561830
On Fri, Mar 20, 2015 at 1:50 PM, Paul A. Bristow
-----Original Message----- From: Boost [mailto:boost-bounces@lists.boost.org] On Behalf Of Beman Dawes Sent: 20 March 2015 13:40 To: Boost Developers List Subject: Re: [boost] [endian] Testing floating point interoperability
An exhaustive return-by-value round-trip test of all 4 billion possible bit patterns for float (but not double) has been run on Windows with the GCC and Microsoft compilers.
For both compilers in release mode, and for GCC in debug mode, all bit patterns pass.
But for Microsoft in debug mode, certain bit patterns do not round-trip correctly. For example, 7f810000 becomes 7fc10000. (Those are little endian representations).
So what should Boost.Endian do? There is less than two weeks left before 1.58.0 ships, and even if this turns out to be a bug in the Microsoft compiler, it is likely to cause user problems.
The most conservative approach is to remove the return-by-value reverse functions, and note in the docs that only in-place reverse is available for FP. That will give us more time to determine if return-by-value endianness reverse is valid for floating point.
Opinions?
I'm not sure.
This looks like a NaN?
As I said before, I'd explicitly not make promises for any NaN except
std::numeric_limits<>::quiet_NaN
(not even the deprecated signalling_NaN)
Anyone using another NaN is likely to be not portable and not expecting Boost to be portable anyway?
But Peter Dimov's objection may be more significant.
+1 --Beman
On March 20, 2015 9:40:22 AM EDT, Beman Dawes
But for Microsoft in debug mode, certain bit patterns do not round-trip correctly. For example, 7f810000 becomes 7fc10000. (Those are little endian representations).
So what should Boost.Endian do? There is less than two weeks left before 1.58.0 ships, and even if this turns out to be a bug in the Microsoft compiler, it is likely to cause user problems.
The most conservative approach is to remove the return-by-value reverse functions, and note in the docs that only in-place reverse is available for FP. That will give us more time to determine if return-by-value endianness reverse is valid for floating point.
Until you have a good handle on the issue, you should not release the functionality as stable and vetted. You might just use a macro to enable those functions as experimental. ___ Rob (Sent from my portable computation engine)
On Fri, Mar 20, 2015 at 4:47 PM, Rob Stewart
On March 20, 2015 9:40:22 AM EDT, Beman Dawes
wrote: But for Microsoft in debug mode, certain bit patterns do not round-trip correctly. For example, 7f810000 becomes 7fc10000. (Those are little endian representations).
So what should Boost.Endian do? There is less than two weeks left before 1.58.0 ships, and even if this turns out to be a bug in the Microsoft compiler, it is likely to cause user problems.
The most conservative approach is to remove the return-by-value reverse functions, and note in the docs that only in-place reverse is available for FP. That will give us more time to determine if return-by-value endianness reverse is valid for floating point.
Until you have a good handle on the issue, you should not release the functionality as stable and vetted.
Understood. That's been uppermost in my mind.
You might just use a macro to enable those functions as experimental.
I'm going to remove all return-by-value functions, including for integers, and there isn't time to do that for 1.58.0. So Boost.Endian will have to wait for 1.59.0. Sigh... Thanks, --Beman
On 03/20/2015 02:40 PM, Beman Dawes wrote:
But for Microsoft in debug mode, certain bit patterns do not round-trip correctly. For example, 7f810000 becomes 7fc10000. (Those are little endian representations).
The two numbers are both Quiet-NaN. They only differ in their payload. The payload is typically used for diagnostics information, so I assume that the two numbers were created in different ways. As the payload is defined by the implementor (according to IEEE 754; C++ is mute here) it could be argued that the above is correct. You may consider masking the payload in the tests.
participants (7)
-
Beman Dawes
-
Bjorn Reese
-
Paul A. Bristow
-
Peter Dimov
-
Rob Stewart
-
Stephan T. Lavavej
-
Steven Watanabe