42

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

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

4

3 回答 3

34

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

来自维基百科的 IEEE 754-1985 无穷值的简短解释:

……剪……

偏置指数字段用全 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;
}
于 2013-11-16T09:44:54.300 回答
9

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

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

(IEC559 是 IEEE754 的 ISO 等效项)

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

于 2013-11-16T09:42:59.657 回答
6

我不知道您使用的是什么编译器,但您可以-std::numeric_limits<double>::infinity()在 gcc 和 MinGw 上使用,请参阅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;

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

于 2013-11-16T09:59:11.780 回答