
Boost : 
From: Paul A Bristow (pbristow_at_[hidden])
Date: 20051117 13:57:16
 Original Message
 From: boostbounces_at_[hidden]
 [mailto:boostbounces_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 nonzero
 _FPCLASS_ND Negative denormalized
 _FPCLASS_NZ Negative zero (  0)
 _FPCLASS_PZ Positive 0 (+0)
 _FPCLASS_PD Positive denormalized
 _FPCLASS_PN Positive normalized nonzero
 _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 genericfunction macro accepts an rvalue argument x of some real
floatingpoint type and evaluates to:
* FP_INFINITE for an argument that is positive or negative infinity
* FP_NAN for an argument that is notanumber (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 implementationdefined 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::numericlimits<floatingpointType>::NaN() and ::quiet_NaN().
But you need to know the floatingpoint 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.openstd.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.unet.com
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk