I am looking to check if a double
value can be represented as an int
(or the same for any pair of floating point an integer types). This is a simple way to do it:
double x = ...;
int i = x; // potentially undefined behaviour
if ((double) i != x) {
// not representable
}
However, it invokes undefined behaviour on the marked line, and triggers UBSan (which some will complain about).
Questions:
- Is this method considered acceptable in general?
- Is there a reasonably simple way to do it without invoking undefined behaviour?
Clarifications, as requested:
The situation I am facing right now involves conversion from double
to various integer types (int
, long
, long long
) in C. However, I have encountered similar situations before, thus I am interested in answers both for float -> integer and integer -> float conversions.
Examples of how the conversion may fail:
- Float -> integer conversion may fail is the value is not a whole number, e.g.
3.5
. - The source value may be out of the range of the target type (larger or small than max and min representable values). For example
1.23e100
. - The source values may be +-Inf or NaN, NaN being tricky as any comparison with it returns false.
- Integer -> float conversion may fail when the float type does not have enough precision. For example, typical
double
have 52 binary digits compared to 63 digits in a 64-bit integer type. For example, on a typical 64-bit system,(long) (double) ((1L << 53) + 1L)
. - I do understand that
1L << 53
(as opposed to(1L << 53) + 1
) is technically exactly representable as adouble
, and that the code I proposed would accept this conversion, even though it probably shouldn't be allowed. - Anything I didn't think of?