Boost logo

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