$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
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