[floats][infinity][C99]

Raymond Toy toy.raymond at gmail.com
Fri Sep 4 16:32:26 UTC 2015


>>>>> "Daniel" == Daniel Kochma <Daniel> writes:

    Daniel> Thanks for reply.
    Daniel> Raymond Toy writes:

    >>>>>>> "Daniel" == Daniel Kochma <Daniel> writes:
    >> 
    Daniel> Hello,
    Daniel> I'm little in doubt. Problem is related to ieee-floating-point
    Daniel> extensions, which provide infinities and nan. Everything works fine
    Daniel> until we generate C code, which simply breaks, because it isn't taken
    Daniel> into account.
    >> 
    Daniel> There are two possible solutions:
    >> 
    Daniel> - for these cases use constant expressions, which trigger an error on
    Daniel> some compilers, that is (0.0 / 0.0) for nan, (1.0 / 0.0) for infinity
    >> 
    >> 
    Daniel> - use defined by C99 macros: INFINITY and NAN, which will work on any
    Daniel> compiler supporting C99.
    >> 
    >> Option 3:  Create them yourself in portable C.  Something like
    >> 
    >> union {
    >> int i[2];
    >> double d;
    >> } u;
    >> 
    >> /* +Infinity */
    >> u.i[MSB] = 0x7ff00000;
    >> u.i[LSB] = 0;
    >> u.d is +Infinity
    >> 
    >> where MSB and LSB are 0 or 1 depending on the endianness of machine.
    >> If you have 64-bit integers, you can replace int i[2] with long i and
    >> just use i = 0x7ff0000000000000;
    >> 
    >> This works for NaN too, but there are many different values for NaN,
    >> so you'll have to choose something.

    Daniel> We have at least three float types – short-float, single-float and
    Daniel> double-float, plus on some architectures long-float. Will this approach
    Daniel> work on all of these types?

Is short-float the same as single-float (like in gcl)?  If so, I think
you can use

    union {
      int i;
      float f;
    }

If long-float is the x87 double-extended (80-bit) float, you'll have to do a
bit more work.  Perhaps something like

    union {
      short s[5];
      long double ld;
    }

    Daniel> Also, we'll have to define such infinity for each architecture
    Daniel> separately, depending on the endianess?

Yes, probably. But you only need to set up MSB/LSB to get the right
thing. I think.  At least that's how fdlibm works and how cmucl
produces it's infinities (in C code).  Of course in Lisp, cmucl has
special builtins to create floats from bits appropriately.  Perhaps
ecl can do something similar. (But there are separate implementations
for each architecture.)

    Daniel> I'm don't know float numbers well enough, but soft floats and hard
    Daniel> floats on arm architecture make any difference for us, or C compiler
    Daniel> will handle it without any intervention?

This is pretty handy:
http://babbage.cs.qc.edu/courses/cs341/IEEE-754.html

While I know long ago soft-floats didn't always match the format of
hard floats, I suspect those days are long gone and any soft float
implementation uses exactly the same format as hard floats.

BTW, pjb pointed out to me (in private) that the union code isn't
truly portable C.  He's right, but for the architectures you're
running on, it should probably work fine.

--
Ray




More information about the ecl-devel mailing list