[gnu.gcc] single precision ieee values

mrm%puffin@Sun.COM (Marianne Mueller Kreuscher) (12/21/89)

I don't think a language extension is necessary, to move a specific
bit pattern into a float or double variable.  You can do it with messy
casts, or define a macro that takes care of the casting for you.

Whether or not (large number * large number) returns the IEEE bit
pattern for infinity probably varies from compiler to compiler, and
from machine to machine.  Depending on how much you care, you might
prefer to spell out the bit patterns yourself.

Clearly there are messy ways to do this and cleaner ways.  The example
here isn't so great but I think it works.   Apologies for sending this
to the gcc mailing list but there seems to be some interest in getting
IEEE support into gcc, and that seems all to the good!  Follow ups
elsewhere, I guess.

--Marianne
mrm@sun.com

---------demo.c
/* single precision IEEE infinity */
#define INF 0x7f800000

/* macro to move single precision value y into x, avoiding unwanted casts */
#define ASSIGNFLOAT(x,y)        *(int *)(&x) = y 

/* double precision IEEE infinity */
#define INF_high 0x7ff00000
#define INF_lo 0x00000000

main()
{

  float x;
  double d;
  int addr;

/* you don't need unions - these are used only to examine the stored values */
  union {float f; unsigned u; } look;
  union {double d; unsigned u[2]; } look_d;

/* single precision: do it yourself, the hard way */
  *(int *)&x = INF;
   printf("x = %g \n", x);

/* single precision: use the macro ASSIGNFLOAT */
  ASSIGNFLOAT(look.f,INF);
  printf("look = %8.7e , or 0x%08x \n\n", look.f, look.u);

/* double precision: same idea, but do it twice */ 
  addr = &d;
  *(int *)addr = INF_high;
  *(int *)(addr+4) = INF_lo;
  printf ("d = %g \n", d); 

/* examine the stored bit pattern */
  look_d.d = d;
  printf("look_d = %g , or 0x%08x 0x%08x \n", 
	 look_d.d, look_d.u[0], look_d.u[1]); 

}