【问题标题】:How to check if a float is infinity/zero/denormal?如何检查浮点数是否为无穷大/零/非正规?
【发布时间】:2017-11-06 15:59:16
【问题描述】:
int is_infinity/is_zero/is_denormal(float f){
    //do something, return 0 or 1
}

这就是我检查float 是否为负数的方法。我想为其他功能做类似的事情,但我不确定如何。

int is_negative(float val){
    union sp_object copy;
    copy.frep = val;
    if((copy.irep & 0x80000000) != 0)
        return 1;
    else
        return 0;
}

【问题讨论】:

  • std::isinf 等。如果你追求各种价值观,也许是std::fpclassify
  • @FrançoisAndrieux - 没关系。 fpclassify 是 C 标准库的一部分。
  • @StoryTeller std::fpclassify 不是
  • 查看函数here。具体在分类和比较部分
  • @HOHO 如果你不需要的话,你真的不想进入位域。 C99 为您提供了更简单的方法

标签: c floating-point


【解决方案1】:

我想为其他功能做类似的事情

避免位字段@David,因为它取决于实现细节。 <math.h> 包含用于对 float 进行分类的宏。这些宏也适用于doublelong double

#include <math.h>

// Adjust returns values as desired.
int is_infinity_is_zero_is_denormal(float f) {
  if (isinf(f)) return 'i';
  if (f == 0.0f) return 'z';
  if (isnan(f)) return 'n';
  if (isnormal(f)) return 0;  // neither zero, subnormal, infinite, nor NaN

  // All that is left is de-normal/sub-normal.
  return 'd';
}

或者干脆

bool is_infinity_is_zero_is_denormal(float f) {
  return !(isnormal(f) || isnan(f));
}

另请参阅int fpclassify(real-floating x);,一步对数字进行分类。

将其参数值分类为 NaN、无限、正常、次正常、零或另一个实现定义的类别。 C11 §7.12.3.1 2

数字分类宏FP_INFINITE FP_NAN FP_NORMAL FP_SUBNORMAL FP_ZERO 表示互斥类型的浮点值。它们扩展为具有不同值的整数常量表达式。 §7.12 6

bool is_infinity_is_zero_is_denormal(float f) {
  // return fpclassify(f) & (FP_INFINITE | FP_ZERO | FP_SUBNORMAL);  // not good
  switch (fpclassify(f)) {
    case FP_INFINITE:
    case FP_ZERO:
    case FP_SUBNORMAL:
      return true;
  }
  return false;
}

让编译器处理优化。

【讨论】:

  • 你的最后一个例子是完全错误的,因为 FP_* 宏不需要定义为 2 的幂,实际上它们不是,至少在 GCC 和 MSVC 中。如果任何宏等于零(实际上FP_ZERO 在 MSVC 中为 0),它可能会有大量误报或根本不起作用。
  • @GiovanniCerretani 同意。帖子已修改。
【解决方案2】:

ISO C99 提供了一个可以比较的INFINITYNAN 宏。推荐使用isfinite()isnormal()isnan()函数。请注意,正如 EOF 指出的那样,与NAN 宏进行比较将无法确定一个值是否实际上是NAN

对于 C99:

https://www.gnu.org/software/libc/manual/html_node/Floating-Point-Classes.html#Floating-Point-Classes

https://www.gnu.org/software/libc/manual/html_node/Infinity-and-NaN.html

对于早期的代码,你不走运:

http://c-faq.com/fp/nan.html

【讨论】:

  • 您无法通过将浮点数与NAN 进行比较来确定它是否为NAN,因为NAN 与所有浮点数比较不等于NAN
猜你喜欢
  • 2023-04-01
  • 1970-01-01
  • 2011-06-11
  • 1970-01-01
  • 1970-01-01
  • 2021-07-02
  • 2015-09-02
  • 1970-01-01
  • 2013-02-25
相关资源
最近更新 更多