Hex Flt Constants at CRI

Tom MacDonald uunet!tamarack.cray.com!tam
Mon Aug 30 14:30:53 PDT 1993


Recently we started a project to implement hex floating-point constants
in the Cray Research C compiler.  Initially we strated implementing the
fp constants in Jim Thomas' "Floating-point C Extensions Document."  It
turned out that several developers were unable to do some of the things
they needed to do with the proposed feature.

I would appreciate hearing any reactions to this deviation from the
Floating-point C Extensions Document, and if anyone else has encountered
similar problems.

Thanks,

Tom MacDonald
Cray Research
tamacray.com

-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Cray Research has decided to implement a form of hexadecimal floating
constants in its C compiler.  The concept was originally derived from
Floating Point C Extensions (X3J11.1/92-040), by Jim Thomas, 3.1.2.1.  An
alternate approach was used in place of the proposal, however.  The scheme
chosen involves representing the actual bit pattern of a floating point
number using a hexadecimal constant.  For example:

	#define INFINITY 0x7fe0000000000000.

Although the nonportability of this method was questioned in the document,
it was realized that for some machines, the proposed approach was no
better.  Since many architectures do not use the IEEE floating point
format, the number of significant bits in the coefficient and exponent
will vary when porting.  Thus the hexadecimal floating constant in either
case will not transfer without modification.  It was also noticed that the
representation of NaNs and infinities was an important need, and the bit
pattern scheme was the best implementation of this.

By looking through some library sources it became apparent that the
`obscurity due to the exponent bias and implicit significand' was no
hindrance to most users, since there are currently many programmers doing
things like:

	union { double d; long i;} pi; 
	pi.i = 0x400921fb54442d18; 

All these factors led to the following Cray Standard C extension: 

========================================================================
Cray Hexadecimal Floating Constants 

As an extension to the C language, this feature is not available when
compiling in strict conformance mode.

A hexadecimal floating constant can be used wherever traditional floating
constants are allowed.

	floating-constant:
		digit-sequence exponent floating-suffix(opt)
		dotted-digits exponent(opt) floating-suffix(opt)
		hexadecimal-floating-constant

	hexadecimal-floating-constant:
		hexadecimal-constant '.' floating-suffix(opt)

The hexadecimal constant has the usual syntax: 0x (or 0X) followed by
hexadecimal characters.  The optional floating suffix has the same form as
for normal floating constants: f or F (for float), l or L (for long),
optionally followed by an i (imaginary).

An additional restriction involves the length of the hexadecimal
constant:  the number of bits represented by the constant (four times the
number of hexadecimal digits, including leading zeros) must exactly match
the number of bits in the type of the constant, which is determined by the
suffix (or the default of double).

For example:
0x7f7fffff.f         for a 32 bit float
0x0123456789012345.  64 bit double

The value of a hexadecimal floating constant is obtained by interpreting
the representation of the value of the hexadecimal-constant as the
representation of a value in the specified floating type.  For this
purpose, an unsigned integral type is used that has the same size as the
floating type (regardless of whether it is possible explicitly to declare
an object with such a type).  No conversion or range checking is
performed.  The resulting floating type value is implementation-defined in
the same way as the result of accessing a member of floating type in a
union after a value has been stored in a different member of integral
type.

Example:

double f=0x3ffe800000000000.;
double g=0xffffffffffffffff.;
main()
{
        printf("f = 0x%16x.f == %g\n",f,f);
        printf("g = 0x%16x.  == %g\n",g,g);
}

Cray Y-MP output:

f = 0x3ffe800000000000.f == 0.125
g = 0xffffffffffffffff.  == *.00000

============================================================================
NOTE:
This feature should be used with care since it is not portable.  The internal
representation of floating point numbers can vary greatly on different
machines, so identical hexadecimal floating constants are very likely to
have different meanings on different architectures.  An understanding of the
underlying structure of floating point storage is essential for utililizing
this constant format.
============================================================================



More information about the Numeric-interest mailing list