繁体   English   中英

C ++浮点到布尔转换

[英]c++ float to bool conversion

我正在查看一些第三方代码,不确定一行到底在做什么。 我无法发布确切的代码,但它遵循以下原则:

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

显然这会向编译器发出有关转换float-> bool的警告,但是实际行为是什么? Visual C ++如何将浮点数转换为布尔值? 至少我应该能够取代那讨厌的无限...

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

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

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

我认为使用isnan()会更好。

如果f不是数字,则isnan()返回true。 但是它将返回true,例如0.0 ...

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

如前所述,这将无法解决f为0.0或非常接近f的情况。

如果您需要,可以通过以下方式进行检查:

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;
    }   
}

检测结果:

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

我通常会

return x != 0;

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

这似乎很简单。 请记住,布尔的唯一状态是零或非零。 所以这段代码:

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

评估如下:

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM