[net.lang.c] How to test for +/- INFINITY, etc. in C with IEEE

ken@turtlevax.UUCP (Ken Turkowski) (12/11/85)

I would like to be able to test for INFINITY, NaN, and other such
things within C.  Now, if I try to cast the value for INFINITY
(0x7F800000 in single) to a float,

	((float)(0x7F800000))

the C compiler changes it into 0x4EFF0000 which does not compare the
same as 0x7F800000.

Can anyone recommend a way to quickly compare a float against
INFINITY?  I can't use a subroutine, because the C compiler changes the
float to a double.

*STEAM follows*

The C compiler should assume that only decimal constants need be
converted from integer to floating point.

Octal and hexadecimal constants are used to represent bit patterns, not
numbers.  There is no reason that the compiler should assume that a
particular bit pattern represents an integer rather than a
floating-point number or something even more exotic.
-- 
Ken Turkowski @ CIMLINC, Menlo Park, CA
UUCP: {amd,decwrl,hplabs,seismo,spar}!turtlevax!ken
ARPA: turtlevax!ken@DECWRL.DEC.COM

ark@alice.UucP (Andrew Koenig) (12/12/85)

> The C compiler should assume that only decimal constants need be
> converted from integer to floating point.

> Octal and hexadecimal constants are used to represent bit patterns, not
> numbers.  There is no reason that the compiler should assume that a
> particular bit pattern represents an integer rather than a
> floating-point number or something even more exotic.

Every constant is an expression.  Every expression has a type.
The meaning of an operator depends only on the type of the expressions
that are its operand and on which operator it is.

If you need to get at the bits in a float, do something like this:

	union {float f; long l;} bits;
	bits.f = ....;
	if ((bits.l & 0x7f800000) == 0x7f800000) ...

jimc@ucla-cs.UUCP (12/13/85)

In article <993@turtlevax.UUCP> ken@turtlevax.UUCP (Ken Turkowski) writes:
>I would like to be able to test for INFINITY, NaN, and other such
>things within C.  Now, if I try to cast the value for INFINITY
>(0x7F800000 in single) to a float,
>
>       ((float)(0x7F800000))
>
>the C compiler changes it into 0x4EFF0000 which does not compare the
>same as 0x7F800000.
>
>Can anyone recommend a way to quickly compare a float against
>INFINITY?
I munged a "C" library with emulated floating point (Microsoft format) to
use an 8087 (IEEE format), but having no sources for the compiler I couldn't
hack the constant interpreter.  I got around it this way:
   short pi[4] = {0x4008,0x1234,etc,etc};
   double x, y;
   x = y * *(double *)pi
A similar method should work for you.  It's ugly but it works, and a
#define macro neatens up the code a little.

James F. Carter            (213) 206-1306
UCLA-SEASnet; 2567 Boelter Hall; 405 Hilgard Ave.; Los Angeles, CA 90024
UUCP:...!{ihnp4,ucbvax,{hao!cepu}}!ucla-cs!jimc  ARPA:jimc@locus.UCLA.EDU

gwyn@brl-tgr.ARPA (Doug Gwyn <gwyn>) (12/16/85)

>    short pi[4] = {0x4008,0x1234,etc,etc};
>    double x, y;
>    x = y * *(double *)pi

Beware!  The alignment applied to (short) data may not be
sufficiently stringent for (double) data, so the result of
the (double *) typecast (assuming the compiler allows it)
may not be suitable for the address of an operand for a
floating-point instruction.  We have machines like that..

You can overcome this problem by proper use of a union.

jsdy@hadron.UUCP (Joseph S. D. Yao) (12/18/85)

In article <993@turtlevax.UUCP> ken@turtlevax.UUCP (Ken Turkowski) writes:
>I would like to be able to test for INFINITY, NaN, and other such
>things within C.  Now, if I try to cast the value for INFINITY
>(0x7F800000 in single) to a float,
>	((float)(0x7F800000))
>the C compiler changes it into 0x4EFF0000 which does not compare the
>same as 0x7F800000.
> ...
>The C compiler should assume that only decimal constants need be
>converted from integer to floating point.

The object 0x80000000 has data type integer, and means a particular
(if somewhat indeterminate) integer.  If I had a constant 0x1 or 01
or 1, I'd expect them all to equal 1.  Their use as bit patterns on
particular machines is wholy machine-dependent.  Try it on Cottrell's
ternary (trinary?) machine!

>Can anyone recommend a way to quickly compare a float against
>INFINITY?  I can't use a subroutine, because the C compiler changes the
>float to a double.

union liffle {		/* long int / float union is a liffle. */
	long int lf_l;
	float lf_f;
};
const union liffle inf = { 0x7f80000 };	/* initialises 1st elem */
#define INFINITY (inf.lf_f)
-- 

	Joe Yao		hadron!jsdy@seismo.{CSS.GOV,ARPA,UUCP}

tim@ism780c.UUCP (Tim Smith) (12/27/85)

In article <130@hadron.UUCP> jsdy@hadron.UUCP (Joseph S. D. Yao) writes:
>
>union liffle {		/* long int / float union is a liffle. */
>	long int lf_l;
>	float lf_f;
>};
>const union liffle inf = { 0x7f80000 };	/* initialises 1st elem */
>#define INFINITY (inf.lf_f)

Aren't you jumping the gun a little here?  The above isn't legal yet!

-- 
Tim Smith       sdcrdcf!ism780c!tim || ima!ism780!tim || ihnp4!cithep!tim