【问题标题】:Can you safely check the sign of infinite?你能安全地检查无穷大的符号吗?
【发布时间】:2014-09-18 09:52:47
【问题描述】:

过去我们一直使用 Visual Studio 的 _fpclass 来了解无限是正数还是负数: http://msdn.microsoft.com/en-us/library/aa246882%28v=vs.60%29.aspx

传递给 std::fpclassify,正无穷和负无穷之间不再有区别: http://en.cppreference.com/w/cpp/numeric/math/fpclassify

我可以用这里的一种方法安全地检查无穷大的符号吗?
Is there a standard sign function (signum, sgn) in C/C++?

注意:

  • 如果启用fastmath,则独立
  • 便携方式

注2:

  • C++11 适用

【问题讨论】:

标签: c++ floating-point


【解决方案1】:

仅检查无限值的符号(如线程标题中所述),此代码就足够了:

template<typename T>
typename std::enable_if<std::numeric_limits<T>::has_infinity, bool>::type Signed(T const& Value)
{
    return Value == -std::numeric_limits<T>::infinity();
}

编辑:如果您可以访问 C++11 就绪的编译器,则标准库还提供了一个函数,在标题 &lt;cmath&gt; 中称为 std::signbit。它适用于每种基本浮点类型和每种类型的值(也适用于无穷大,甚至适用于 NaN),因此应该是更通用的解决方案。

【讨论】:

  • 如果您还可以提及 Mark Dickinson 链接的符号位功能,这将是我接受的答案。
  • @Antonio 是的,我能做到。
【解决方案2】:

您实际上并不需要任何特殊函数来检测无穷大和 NaN:

double x = ...;
bool is_nan = x != x;
bool is_finite = !is_nan && x != 2 * x;
bool is_negative = !is_nan && x < 0;

【讨论】:

  • +1。作为数字,+inf-inf 并不是特别特别。大多数算术运算都不会产生nans,而且它们的比较与任何其他数字一样。
  • 重点是,x != x 在启用快速数学时可能会返回 false!
  • @Antonio 不要启用那些搞砸你数学的选项。快而错不是美德。
  • 此代码不可移植,因为 x != x 不是 NaN 浮点数的可移植分类。编译器甚至没有被强制使用 IEEE 浮点标准。
  • @MaximYegorushkin 这是一本书中的“评论”部分,它本身就是一个人对 C 和 C++ 标准的评论。它没有写得那么严格,以至于句子“A NaN 总是比较不等于任何其他值,即使是相同的 NaN”也不能解释为意味着“A [IEEE-754] NaN 总是比较不等于任何其他值,即使是相同的NaN”,因为 IEEE 754/IEC 60559 是前面几句话中讨论的主题。除非相关编译器确认其支持 IEC 60559,否则此处没有任何内容对 C 或 C++ 编译器具有约束力。
【解决方案3】:

您似乎已经知道x 是正无穷还是负无穷,只是不知道是哪个。在这种情况下,如果您知道 x7-7 但不知道是哪个,您会使用相同的策略:

x > 0

这并没有错。当然x &gt; 24 或与任何其他有限值的比较都可以,因为正无穷大于所有有限值而负无穷小于所有有限值,但与0 比较似乎是检查签名。

如果您不确定x 是否为无穷大,请按照 Fytch 的回答中的建议进行明确测试:

if (x == std::numeric_limits<double>::infinity()) {
    // positive infinity
} else if (x == -std::numeric_limits<double>::infinity()) {
    // negative infinity
} else {
    // something else
}

【讨论】:

    猜你喜欢
    • 2017-08-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-18
    • 1970-01-01
    • 2018-12-22
    • 1970-01-01
    相关资源
    最近更新 更多