c ++ float to bool conversion

时间:2009-12-28 14:05:18

标签: c++ visual-c++

我正在查看一些第三方代码,并且我不确定一行正在做什么。我无法发布确切的代码,但它是:

bool function(float x)
{
float f = doCalculation(x);
return x > 0 ? f : std::numeric_limits<float>::infinity();
}

这显然会引发编译器关于转换float-&gt; bool的警告,但实际行为是什么? Visual C ++如何将浮动转换为bools?至少我应该能够取代那令人讨厌的无限......

6 个答案:

答案 0 :(得分:22)

我认为这是一个错误。该函数应该返回一个浮点数。这对我来说似乎是合乎逻辑的。

将float转换为bool与float!= 0相同。但是,由于精度的原因,严格比较两个浮点并不总是如你所愿。

答案 1 :(得分:2)

如果它的== 0.0f,浮点数将转换为false,但要注意精度!否则它将被转换为true - 如果它不是 exacly 0.0f,它也将是true! Inifinity也将转换为true。正如David Thornley所说,你的例子是非常糟糕的代码。

答案 2 :(得分:1)

我认为最好使用 isnan()

如果f不是数字,则

isnan()返回true。但它会在例如0.0 ...

#include <cmath>
bool function(float x)
{
    float f = doCalculation(x);
    return isnan(f) ? false : true;
}

如上所述,不会发现f为0.0 - 或非常接近它的情况。

如果您需要,可以查看:

bool near0 = std::abs(f) > std::numeric_limits<float>::epsilon();

编辑:这是一个包含测试驱动程序的改进示例:

#include <cmath>

#include <limits>
#include <iostream>
#include <vector>

// using namespace std;
bool fn(float f) {
    if (isnan(f)) return false; // it is not-a-number
    return std::abs(f) > std::numeric_limits<float>::epsilon();
}

// testdriver
int main(void) {
    std::vector<float> t;
    t.push_back(0.0);
    t.push_back(0.1);   
    t.push_back(-0.1);
    t.push_back( 0.0 + std::numeric_limits<float>::epsilon());  
    t.push_back( 0.0 - std::numeric_limits<float>::epsilon());
    t.push_back( 0.0 - 2*std::numeric_limits<float>::epsilon());
    t.push_back( 0.0 + 2*std::numeric_limits<float>::epsilon());
    t.push_back( 1.0 * std::numeric_limits<float>::epsilon());      
    t.push_back(-0.1 * std::numeric_limits<float>::epsilon());
    t.push_back( 0.1 * std::numeric_limits<float>::epsilon());
    for (unsigned int i=0; i<t.size(); i++) {
        std::cout << "fn(" << t[i] << ") returned " << fn(t[i]) << std::endl;
    }   
}

testresults:

fn(0) returned 0
fn(0.1) returned 1
fn(-0.1) returned 1
fn(1.19209e-07) returned 0
fn(-1.19209e-07) returned 0
fn(-2.38419e-07) returned 1
fn(2.38419e-07) returned 1
fn(1.19209e-07) returned 0
fn(-1.19209e-08) returned 0
fn(1.19209e-08) returned 0

答案 3 :(得分:0)

我一般都是

return x != 0;

答案 4 :(得分:0)

假设DoCalculation(x)为x的非正值返回infinity(),则对于DoCalculation()的非零值,x function(x)的正值为true,否则为false。因此,函数(x)用于确定DoCalculation(x)是否为零。我将函数(x)重命名为IsDoCalculationNonzero(x)。

答案 5 :(得分:0)

这看起来非常简单。请记住,bool识别的唯一状态是零或非零。所以这段代码:

return x > 0 ? f : std::numeric_limits<float>::infinity();

评估如下:

如果x> 0:返回f。如果f == 0.0F则返回false。  否则它将返回true。正如其他人所提到的那样,精确度问题可能会给出错误的判断,但如果它正在发挥作用那么我就不会说......

如果x <= 0:返回无穷大(),这是一个奇怪的情况。但是,infinity()!= 0 - 因此这将返回true。 (参考:http://msdn.microsoft.com/en-us/library/85084kd6.aspx