R
rz0
Hi all,
This is a question about both C89 and C99 and is based on my partial
reading of the standard drafts (one from before C89 but mainly
N1124). If appropriate, please give a separate answer for each version
of the language.
Let's consider the conversion from a given floating real type to a
specific integer type.
Given a value of floating real type Tf, unknown at compile-time. What
is the safest way to convert it to a value of integer type Ti (other
than _Bool), without invoking Undefined Behavior due to out of range
error? The standard says that whenever the value would not be
representable in the converted-to type, the result would be undefined.
Yet, how do I test for valid values?
I thought there would be a macro in limits.h or float.h or maybe
stdint.h, for C99, to indicate the valid range of floating-point
values of a given type that may be converted safely from but did not
find any. I thought about testing the macros defining maximal values
of integer types but then, the test itself would invoke UB if *_MAX
were out of range of representable values, for the double type.
I did find the lrint family of functions, which only have unspecified
results when the converted value is not representable. However, it is
only part of the C99 specifications as far as I know and I would
rather have a single solution for both versions.
I am also interested in conversions from int to double, the problem is
much the same. Besides, there is no lxdbl function that would do the
opposite of lrint.
Narrowing the problem to the conversions from double to int and vice
versa, when I started learning C some years ago (by the way, I'm still
learning), I was told that the range of double was always greater than
that of int. Yet, I am unable to find in my copy of the drafts a
section where this is stated. If it is indeed the case, then the
conversion from int to double cannot cause UB and the opposite could
easily be made safe by converting INT_MAX to double and comparing to
the value which is to be converted. Could you then point out the
relevant sections for me to check by myself?
There is probably something I have missed in my reading of the drafts
or that I have not thought about, so please give advice.
Thanks in advance.
This is a question about both C89 and C99 and is based on my partial
reading of the standard drafts (one from before C89 but mainly
N1124). If appropriate, please give a separate answer for each version
of the language.
Let's consider the conversion from a given floating real type to a
specific integer type.
Given a value of floating real type Tf, unknown at compile-time. What
is the safest way to convert it to a value of integer type Ti (other
than _Bool), without invoking Undefined Behavior due to out of range
error? The standard says that whenever the value would not be
representable in the converted-to type, the result would be undefined.
Yet, how do I test for valid values?
I thought there would be a macro in limits.h or float.h or maybe
stdint.h, for C99, to indicate the valid range of floating-point
values of a given type that may be converted safely from but did not
find any. I thought about testing the macros defining maximal values
of integer types but then, the test itself would invoke UB if *_MAX
were out of range of representable values, for the double type.
I did find the lrint family of functions, which only have unspecified
results when the converted value is not representable. However, it is
only part of the C99 specifications as far as I know and I would
rather have a single solution for both versions.
I am also interested in conversions from int to double, the problem is
much the same. Besides, there is no lxdbl function that would do the
opposite of lrint.
Narrowing the problem to the conversions from double to int and vice
versa, when I started learning C some years ago (by the way, I'm still
learning), I was told that the range of double was always greater than
that of int. Yet, I am unable to find in my copy of the drafts a
section where this is stated. If it is indeed the case, then the
conversion from int to double cannot cause UB and the opposite could
easily be made safe by converting INT_MAX to double and comparing to
the value which is to be converted. Could you then point out the
relevant sections for me to check by myself?
There is probably something I have missed in my reading of the drafts
or that I have not thought about, so please give advice.
Thanks in advance.