On Wed, 17 Mar 2004, Norman Gray wrote:
> Here's what I now think is the full (?) story about bad values,
> condensing various folk's comments, plus a bit of scouting around.
>
> -- Primdat, HDS and IMG all _separately_ define bad values,
> which match, though they aren't taken from a common source.
>
> -- Primdat specifies its bad values in files prm_par_* as hex integers
> interpreted as floats (where the Fortran compiler supports that VAX
> Fortran extension), or as magic float values which match those integers.
> It therefore doesn't have to worry about endianness, since the bytesex
> of integers is the same as the bytesex of floats; we can distinguish this
> from specifying a bit pattern, which would be a bytesex-independent thing
> (for the purposes of the discussion below: 12345678 is the same integer
> on a big- and little-endian machine, but different bit patterns).
>
> -- As it happens (apparently, though this isn't noticably documented in
> the Primdat sources) these bad values are the same as the most negative
> float and double, -FLT_MAX and -DBL_MAX from <float.h>. However none
> of the primdat definitions use float.h.
Not surprising since this is developed for Fortran, not C.
> -- This has to be the case, since the primdat, img and hds bad values
> must be the same.
>
> -- The HDS bad values are explicitly the most negative values for floats
> and signed integer types (for example -FLT_MAX and INT_MIN), and the
> maximum values for unsigned integer types. These aren't specified in
> a header file, but initialised in HDS's dat1_init_ndr.c, based on the
> values in float.h. Somewhat surprisingly, these seem _not_ to be written
> to a header file anywhere. It's essentially the result of
> dat1_init_ndr.c that hds_machine.f reports, and puts into
> hds_datestamp, but this is purely informational, and isn't
> machine-readable.
Again not really surprising, PRIMDAT predates the need for HDS to know
about different machine types. So all this information that HDS now has is
essentially "new" (well on the timescale of a decade or so!).
> -- That means that the HDS bad float value is the same as integer ff7fffff
> on both big- and little-endian IEEE machines, and the same as integer
> ffffffff on VAXes (that's the most negative f_float; float ff7fffff is
> a legal VAX float, but not the most negative one). That's presumably
> why (as Malcolm reports) SUN/39 lists ffffffff as the primdat bad float.
>
> -- Thus there isn't a fixed bit pattern, nor even a fixed integer
> equivalent, which is the bad value stored in HDS files (ain't HDS
> clever): this is presumably a good thing for the prospective 64-bit HDS
> and primdat.
Exactly, it is a good design really. Efficient native data access, plus
portability, eat your heart out FITS and binary dumps and the like.
> -- Thus the VAX and IEEE bad values don't have the same integer
> equivalent, nor the same numerical value (-1.7e38 and -3.4e38
> respectively), and the way that HDS's dat1_cvt_format.c handles this
> appears to be by explicitly spotting one format's bad value on input
> and replacing it with the other.
>
> -- Primdat slightly complicates this by defining both NUM__MINR, which
> is the most negative float (and thus necessarily identical to
> VAL__BADR) and VAL__MINR, which is the most negative non-bad float (and
> thus necessarily the next float after NUM__MINR). It defines the
> latter with a hex integer, and thus _not_ using float.h, and thus not
> portably to VAXes (big deal) or 64-bit machines (which would require
> special handling here anyway).
All hail Brian...
> SO:
>
> I think the best thing would be for me to modify HDS so that it generates
> and installs Fortran and C include files which define the bad values
> which it expects on the local platform, plus the minimum and maximum
> values, and the minimum and maximum non-bad values, all based on float.h.
Sounds good.
> Perhaps call them HDS__BADR, HDS__MINRX and HDS__MINR (etc). Then either
> (a) components like IMG or primdat reprocess these headers into their
> own headers (though there might be worries about converting these back
> and forth into decimal representation); or (b) we lose prm_par and (the
> relevant parts of) img.h and have those applications just use the HDS
> values instead (probably more reliable, and might require little more
> than a bit of sedding, but it would temporarily break any applications
> outside our tree which use these headers -- are there any?).
Loads, the breaking existing include files is a no no. These just need to
"#include" and "INCLUDE" the new HDS files.
Peter.
|