|
Boost : |
From: Paul A Bristow (pbristow_at_[hidden])
Date: 2005-11-17 13:57:16
| -----Original Message-----
| From: boost-bounces_at_[hidden]
| [mailto:boost-bounces_at_[hidden]] On Behalf Of Robert Ramey
| Sent: 17 November 2005 18:00
| To: boost_at_[hidden]
| Subject: [boost] serialization - NaN, +/Inf and others
|
| Troy S. and I have been looking at the question of implementing
| serialization
| of NaN, +/-Inf for floats, and doubles for portable text or
| binary archives.
|
| Turns out there's a fly in the ointment.
|
| For determining if a given double contains a "special" value, float.h
| contains the following handy function
|
| int _fpclass(
| double x
| );
|
| which returns one of the following values:
|
| _FPCLASS_SNAN Signaling NaN
| _FPCLASS_QNAN Quiet NaN
| _FPCLASS_NINF Negative infinity ( -INF)
| _FPCLASS_NN Negative normalized non-zero
| _FPCLASS_ND Negative denormalized
| _FPCLASS_NZ Negative zero ( - 0)
| _FPCLASS_PZ Positive 0 (+0)
| _FPCLASS_PD Positive denormalized
| _FPCLASS_PN Positive normalized non-zero
| _FPCLASS_PINF Positive infinity (+INF)
|
|
| So we could write a flag to the archive indicating if its a
| special value.
|
| So far, so good.
|
| When the archive is read back, we can read the flag and initialize
| the variable with the appropriate value.
|
| BUT - I can't find any "official" to initialize a
| float/double to any of
| these
| values. They seem to be the result of operations and its certainly
| not obvious that all compilers would be on the same page here.
|
| Note that this same problem arises whenever a float/double is
| written/read
| to/from a stream in a way designed to be portable. So it
| must have come
| up before. What's the solution here?
|
| Robert Ramey
Dinkumware says that C99 math.h (to be added to C++ by TR1) provides
fpclassify
#define fpclassify(x) <int rvalue> [added with C99, int functions in C++]
The generic-function macro accepts an rvalue argument x of some real
floating-point type and evaluates to:
* FP_INFINITE for an argument that is positive or negative infinity
* FP_NAN for an argument that is not-a-number (NaN)
* FP_NORMAL for an argument that is finite and normalized
* FP_SUBNORMAL for an argument that is finite and denormalized
* FP_ZERO for an argument that is positive or negative zero
or possibly some other implementation-defined value.
But of course their VALUES are not specified in the standard.
C Macros for INFINITY, NAN are provided (in C99 if not alrady)
and will probably be used to implement the C++ functions which return
std::numeric-limits<floating-pointType>::NaN() and ::quiet_NaN().
But you need to know the floating-point type of course.
Denormalised probably don't need to be treated any differently. For
hardware that doesn't deal with denormalised (VAX/ALPHA?) can't be portable
anyway?
The positive and negative infinties and zeros really are different in
representation in MS world at least, but I fear you may just have to ignore
that.
http://www2.open-std.org/JTC1/SC22/WG14/www/C99RationaleV5.10.pdf
does not provide any rationale for the lack of sign on infinity and zero.
Getting -zero is unlikely to be a problem, but getting +infinity instead of
-infinity could be most confusing - as different as you can get ;-)
I suspect C99 put it in the 'too difficult' box?
HTH
Paul
-- Paul A Bristow Prizet Farmhouse, Kendal, Cumbria UK LA8 8AB Phone and SMS text +44 1539 561830, Mobile and SMS text +44 7714 330204 mailto: pbristow_at_[hidden] www.hetp.u-net.com
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk