Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Conversion from double to float, and undefined behaviour.

6 views
Skip to first unread message

Mark Dickinson

unread,
Jul 18, 2010, 11:13:43 AM7/18/10
to
I'm dealing with some code that (for the purposes of serialization)
explicitly
casts a double to a float. In essence, it looks like this:

#include <math.h>
#include <stdio.h>

void f(double x) {
float y = x;

if (isinf(y) && !isinf(x))
printf("Deal with overflow here\n");
else
printf("Do something with %.17g\n", y);
}

However, according to C99 6.3.1.5p2, converting a finite value that's
"outside
the range of values that can be represented" as a float gives
undefined behaviour.
How would you rewrite the above to avoid undefined behaviour? The
obvious
solution is to check whether fabs(x) > FLT_MAX before converting.

But:

This isn't quite the same thing, since some values that are *only
just* greater
than FLT_MAX would normally be expected to round down to FLT_MAX, so
the
boundary is actually something like (assuming IEEE 754 floats and
doubles)

FLT_MAX / (1 - 0.5 * FLT_EPSILON) * (1 - 0.25 * FLT_EPSILON)

So the question is: what's the exact meaning of "outside the range of
values
that can be represented" in C99 6.3.1.5p2? For converting from double
to
float, is the relevant range only up to (and including) FLT_MAX, or
can I
assume that I'm safe all the way up to (but not including) the
slightly larger
bound above?

(Note: on the platforms I care about, it's realistic to assume that
double
and float are IEEE 754 binary64 and binary32 formats, respectively,
and
that conversion from double to float uses round-half-to-even.)

--
Mark

Ben Bacarisse

unread,
Jul 18, 2010, 12:45:27 PM7/18/10
to
Mark Dickinson <dick...@gmail.com> writes:

I can't really address the underlying issue, but the wording seems to be
unambiguous. The C standard defines a model of floating point numbers
in which there is an unambiguous range of representable numbers.
Likewise the value being converted is an exact rational number and will
either be in or outside of the range of the target type.

It is possible that the standard intended to include rounding in this
phrase, but that seems unlikely since it is explicitly mentioned in the
preceding sentences.

> For converting from double to float, is the relevant range only up to
> (and including) FLT_MAX, or can I assume that I'm safe all the way up
> to (but not including) the slightly larger bound above?
>
> (Note: on the platforms I care about, it's realistic to assume that
> double and float are IEEE 754 binary64 and binary32 formats,
> respectively, and that conversion from double to float uses
> round-half-to-even.)

The fact that you mention a specific FP implementation suggests that you
are not so much concerned with what the standard says is UB but what
IEEE FP systems actually do in these situations. That I can't speak to.

The fact the C makes it UB does not mean that anything bad will happen.
It simply gives implementations license do what they like -- probably
because some FP systems "go wrong" in exactly this situation.

--
Ben.

0 new messages