c++ - 检查 float 是否可以表示为整型

标签 c++ undefined-behavior

如何检查 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/

相关文章:

c++ - 检查子类的构造函数是否在 C++ 中是公共(public)的

c++ - 函数返回指针的未定义行为

c++ - 这是不确定的吗?

c++ - C++ 函数返回错误值

c++ - 如何更改 QMessageBox 图标和标题

c - 在 printf 函数中使用增量运算符 (++) 时出现奇怪的结果

c - 未初始化的变量如何获得随机值?

c++ - 从指向具有相同签名的函数的指针转换为函数指针,但参数的附加限定除外

c++ - 为堆栈分配的对象调用析构函数的机制是什么?

c++ - 代码覆盖率 (Lcov) 错误地显示 100% 覆盖率