On Tue, 16 Mar 2004, Norman Gray wrote:
> First is the statements initialising reals with hex values:
>
> REAL VAL__BADR
> PARAMETER ( VAL__BADR = 'FF7FFFFF'X )
>
> I can see what that's doing, but it looks veeeery dodgy. Can anyone point
> to any details about this? I can't find any support for that syntax
> in the Fortran standard, though that's rather confusingly arranged and
> I could have missed it, and I'd confidently say it was a VAXFortran
> extension except that the Sun files have it, too. Given that, the
> PRM_PAR files are actually less different from each other than they
> might appear, so that they're precarious rather than terribly
> non-standard.
Norman,
the bad values are written this way as you need to get a specific bit
pattern that signifies a certain value. The 'X hexadecimal constant
notation was in VAX fortran which is where the practice came from. The
differences (if any) are just how the bit patterns could be most reliably
generated on a specific machine (when we used f2c, before g77 was
developed, it didn't support this extension, causing a few headaches, and
explains the "two" Linux versions).
> Secondly, what is the idea behind the bad values, and how magic are
> the particular values? Are they just a sort of non-IEEE-specific NaN?
> Or are they a specific flag value that would possibly find its way into
> files (in which case the actual values couldn't ever be changed)?
BAD values are written into files, hence the need to be a specific bit
pattern (remember this all existed way before NaNs were a twinkle in
anyones eyes).
> I don't think they can be specific values, because the header of
> PRM_PAR says ``This file defines machine-dependent public constants
> for the PRIMDAT system'', and they _are_ machine-dependent, because
> the various PRM_PAR source files define the _same_ bit patterns on both
> big- and little-endian machines. Unless, that is (and this is the link
> with the first question), the 'hex'X notation has its value ordered in
> significance order rather than memory order.
BAD values are written to files, and are machine specific (although the
machine specific reference in PRM_PAR is probably meant to apply more to
all the other values, VAL__EPSR, VAL__MAX... etc.), that's because HDS
files are written using the native byte ordering of a machine. HDS is a
clever chap and notices the byte order of the file and converts it to the
ordering of the machine before the program sees it. There's a command
"NATIVE" in KAPPA that makes this transformation permanent.
> And what's with those bit patterns? Given that that FF7FFFFF is just
> an integer (that is, it's in significance order rather than memory
> order, which makes sense), then it corresponds to the most negative
> finite IEEE float, and that means that VAL__BADR is equal to NUM__MINR,
> which is slightly surprising. But then this is clearly not a special
> number on a VAX -- and possibly not even a legal float, I can't remember.
> So this can't be a platform-independent bad value that would ever find its
> way into a file, and it's just a flag value that's possibly returned by
> certain VAL_* functions, and it doesn't matter that there's a theoretical
> chance that a bad value would be the correct result of a calculation.
Again the magic is in HDS. If it saw a VAX-native file it would make the
VAX BAD values some UNIX BAD values (if they were different, I don't think
they are as a bit pattern, but that's been a long time, look in HDS that
may make this point clear if it matters).
> This does seem to match how they're explained in SUN/39.
>
> It would also be sensible, I think, to take the minimum and maximum
> values from something like float.h, and just set the VAL__BADR and
> NUm__MINR values, for example, to be the same as float.h's FLT_MIN.
Yes, from img.h:
/* Define BAD values. */
#include <float.h>
#include <limits.h>
#define VAL__BADF -FLT_MAX
#define VAL__BADD -DBL_MAX
#define VAL__BADI INT_MIN
#define VAL__BADS SHRT_MIN
#define VAL__BADUS USHRT_MAX
#define VAL__BADB CHAR_MIN
#define VAL__BADUB UCHAR_MAX
These bit patterns are indeed the min/max values of the various types.
> Thus, yes, I'll make a new prm.h file primary, and effectively generate
> PRM_PAR from that.
>
> All this will be wrong on a 64-bit machine, of course.... Ah no, it
> wouldn't be, not if it's taken from float.h! So that's a Good Thing.
> I think.
>
> Also, I think that PRM_PAR doesn't have to worry about whether it's on
> a big- or little-endian machine. Which is also Good.
That's rights. That's a worry for HDS.
> Right: that's probably a bit clearer to me (thanks for listening).
> Any words of wisdom to add to that, anyone?
See above.
Peter.
|