【问题标题】:Negative infinity负无穷大
【发布时间】:2013-11-29 18:17:48
【问题描述】:

我试图弄清楚如何将负无穷大的值分配给浮点或双精度变量。似乎包括标准库限制,我可以获得无穷大表示,并且我知道(非常肯定)在它前面添加一个减号(-infinity)可能会导致我在 IEEE754 浮点中寻找的值标准(因为 0x7FFFFFFF 可能会导致 0xFFFFFFFF),但我什至不确定,更不用说可能存在的其他标准(如果有的话)。我发现它非常非常不专业并且依赖于实施。

有没有什么好的方法可以独立获取负无穷平台的值和实现,不然我还不如用#define,大家都喜欢预处理。

【问题讨论】:

  • 只是出于好奇,你为什么还要-inf?
  • 我有一个图表,我想确定哪个邻居是最好的选择(它是某种游戏的人工智能)但是为每个邻居节点分配一个数字的函数可以返回大的负数。为了检查最大值,我想将变量初始化为一个与任何东西相比总是会导致“小于”的值,当然还有其他方法可以做到这一点,但是当我没有找到 -inf我很好奇,因为我知道的所有其他编程语言都有正无穷和负无穷值的定义。
  • 也许您应该为此使用第一个元素,而不是负无穷大?
  • 当然,您可以随时使用-1/.0。非常适合打高尔夫球。
  • @Setzer22 - 如果“数学上准确”的意思是“与实数完全一样”,那么浮点数学中的任何内容都不是“数学上准确的”。浮点数学有自己的一套规则,你必须使用它定义的系统,而不是你习惯的系统。 <g> 接近实数的情况,但不一样。

标签: c++ numeric-limits


【解决方案1】:

如果std::numeric_limits<double>::is_iec559 是true 那么它应该可以安全使用-

double negative_infinity = - std::numeric_limits<double>::infinity();

(IEC559 是 IEEE754 的 ISO 等效项)

如果是false,那么还有很多工作要做,因为我认为 C++ 标准不会给你任何帮助。

【讨论】:

  • std::numeric_limits<double>::has_infinity 理论上即使在非 IEEE754 平台上也是如此,尽管我怀疑是否存在许多这样的平台。
  • 是的,但这只能保证会有一个正无穷大。在使用的任何系统下,负无穷大可能仍然无法表示,我认为没有任何测试方法。
【解决方案2】:

至少如果std::numeric_limits::is_iec559 (IEEE 754) 为真(这保证std::numeric_limits::has_infinity 也为真),您可以按照您已经说明的方式表达正无穷大值和负无穷大值。

来自Wikipedia 的 IEEE 754-1985 无穷值的简短说明:

......剪辑......

biased-exponent 字段用全 1 位填充以指示任一 无穷大或计算的无效结果。

正无穷和负无穷

正无穷和负无穷表示如下:

 sign = 0 for positive infinity, 1 for negative infinity.
 biased exponent = all 1 bits.
 fraction = all 0 bits.

......剪辑......

断言

以下示例将按预期工作,或者在目标平台不支持 IEEE 754 浮点数的情况下导致编译时错误。

#include <cstdlib>
#include <cmath>
#include <cassert>
#include <limits>

int main(void)
{
    //Asserts floating point compatibility at compile time
    static_assert(std::numeric_limits<float>::is_iec559, "IEEE 754 required");

    //C99
    float negative_infinity1 = -INFINITY;
    float negative_infinity2 = -1 * INFINITY;

    float negative_infinity3 = -std::numeric_limits<float>::infinity();
    float negative_infinity4 = -1 * std::numeric_limits<float>::infinity();

    assert(std::isinf(negative_infinity1) && negative_infinity1 < std::numeric_limits<float>::lowest());
    assert(std::isinf(negative_infinity2) && negative_infinity2 < std::numeric_limits<float>::lowest());
    assert(std::isinf(negative_infinity3) && negative_infinity3 < std::numeric_limits<float>::lowest());
    assert(std::isinf(negative_infinity4) && negative_infinity4 < std::numeric_limits<float>::lowest());

    return EXIT_SUCCESS;
}

【讨论】:

  • 顺便说一句,int main(void) 而不是 int main() 和 return EXIT_SUCCESS; 在 C++ 中是不需要的。
【解决方案3】:

我不知道您使用的是什么编译器,但您可以在 gcc 和 MinGw 上使用 -std::numeric_limits&lt;double&gt;::infinity(),请参阅 Infinity-and-NaN。我还在 MSVC 上运行了以下代码,它返回了 true:

double infinity(std::numeric_limits<double>::infinity());
double neg_infinity(-std::numeric_limits<double>::infinity());
double lowest(std::numeric_limits<double>::lowest());

bool lower_than_lowest(neg_infinity < lowest);
std::cout << "lower_than_lowest: " << lower_than_lowest << std::endl;

但是,可能值得考虑在您的应用程序中使用最低而不是负无穷,因为它可能会产生更便携的解决方案。

【讨论】:

  • 使用最低的而不是-inf 很好,你说得对,在问我实际上找到了更好的解决方案时,我只是出于好奇而问,但我会考虑到我将来可能遇到的问题
猜你喜欢
  • 2017-08-19
  • 2015-03-22
  • 1970-01-01
  • 1970-01-01
  • 2012-02-09
  • 2022-08-12
  • 2016-08-13
  • 2015-07-06
  • 1970-01-01
相关资源
最近更新 更多