符合标准的方法来比较浮点数和积分值?

orl*_*rlp 8 c++ floating-point comparison integer language-lawyer

比方说,我有两个对象if相应的类型IF.我知道这std::is_integral<I>::value是真的,而且std::is_floating_point<F>::value是真的.

是否有完全符合标准的方法来确定值i是否小于f?的值?请注意强调"完全符合标准",对于这个问题,我只对那些由C++标准保证支持的答案感兴趣.


琐碎的实现i < I(f)不起作用,因为它的值f可能不适合i.平凡的实现F(i) < f也不起作用,因为精度f可能不足以表示i,导致i四舍五入到等于f(如果你有IEEE754浮点数,16777219 < 16777220.f失败)的值.

但是这里出现了真正的困境:如果你想用来std::numeric_limits::max缓解这些问题,你可以回到比较浮点数和整数的原始问题!这是因为类型std::numeric_limits::max等于原始类型.

aka*_*ice 0

我就是这样做的:

我假设 f 是有限的,无限和 NaN 的情况将在其他地方处理。

  1. 比较 f 和 F(i),如果不相等,则完成,f 和 i 要么 < 要么 >

  2. 如果相等,则比较 I(f) 和 i

唯一的假设是:

  • 如果存在一个恰好具有值 i 的浮点数,则 F(i) 给出该值

  • 如果存在一个与 f 的值完全相同的整数,则 I(f) 给出该值

  • 函数 F 和 I 的单调性

编辑

更明确地说,以上技巧是用于编写比较函数,而不仅仅是测试相等性......

floatType F(intType i);
intType I(floatType f);
int cmpfi(floatType f,intType i)
{
  assert(isfinite(f));
  if(f < F(i)) return -1;
  if(f == F(i))
  {
    if( I(f) < i ) return -1;
    return I(f) > i;
  }
  return 1;
}
Run Code Online (Sandbox Code Playgroud)

由您决定将此草稿转换为可以处理几种不同 floatType/intType 的 C++ 代码