如何检查 float
是否可以表示为整数类型,而无需通过强制转换调用未定义的行为?这是 §4.9.1 禁止的:
A prvalue of a floating point type can be converted to a prvalue of an integer type. The conversion truncates; that is, the fractional part is discarded. The behavior is undefined if the truncated value cannot be represented in the destination type,
有 this C 的问题,但接受的答案显然会导致未定义的行为(首先是简单的转换,然后是使用 union hack,这让整个事情对我来说非常可疑)。
我可以看出拥有一个完全兼容的解决方案是多么困难,但是实现定义的解决方案(假设 IEEE-754 float )也是可以接受的。
最佳答案
检查 truncf(x) == x
. (该函数在 <math.h>
中)当且仅当 x 没有小数部分时,它才会比较真。然后,将 x 与类型的范围进行比较。
示例代码(未测试)
#include <cfenv>
#include <cmath>
#pragma STDC FENV_ACCESS on
template<class F, class N> // F is a float type, N integral.
bool is_representable(const F x)
{
const int orig_rounding = std::fegetround();
std::fesetround(FE_TOWARDZERO);
const bool to_return = std::trunc(x) == x &&
x >= std::numeric_limits<N>.min() &&
x <= std::numeric_limits<N>.max();
std::fesetround(orig_rounding);
return to_return;
}
舍入设置为零时,整数类型的最小值和最大值到浮点类型的隐式转换不应溢出。在许多架构上,包括 i386,转换为 long double
还将提供足够的精度来准确表示 64 位 int。
关于c++ - 检查 float 是否可以表示为整型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32810978/