检查float是否可以表示为整数类型

Voo*_*Voo 5 c++ undefined-behavior

如何在不float通过强制转换调用未定义的行为的情况下检查a是否可以表示为整数类型?这是§4.9.1禁止的:

可以将浮点类型的prvalue转换为整数类型的prvalue.转换截断; 也就是说,丢弃小数部分.如果截断的值无法在目标类型中表示,则行为未定义,

对于C来说存在这个问题,但是接受的答案显然会导致未定义的行为(首先是通过简单的转换而后来通过使用联合黑客,这使得整个事情对我来说非常可疑).

我可以看到如何拥有一个完全兼容的解决方案,但实现定义(假设IEEE-754浮点数)也是可以接受的.

Dav*_*lor 0

查看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;
}
Run Code Online (Sandbox Code Playgroud)

将舍入设置为零时,整型的最小值和最大值到浮点类型的隐式转换不应溢出。在许多体系结构(包括 i386)上,转换为long double也将提供足够的精度来精确表示 64 位 int。