简体   繁体   English

C ++浮点到布尔转换

[英]c++ float to bool conversion

I'm looking at some 3rd party code and am unsure exactly what one line is doing. 我正在查看一些第三方代码,不确定一行到底在做什么。 I can't post the exact code but it's along the lines of: 我无法发布确切的代码,但它遵循以下原则:

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

This obviously throws a warning from the compiler about converting float->bool, but what will the actual behaviour be? 显然这会向编译器发出有关转换float-> bool的警告,但是实际行为是什么? How does Visual C++ convert floats to bools? Visual C ++如何将浮点数转换为布尔值? At the very least I should be able to replace that nasty infinity... 至少我应该能够取代那讨厌的无限...

I think it is a mistake. 我认为这是一个错误。 That function should return a float. 该函数应返回一个浮点数。 This seem logical to me. 在我看来,这是合乎逻辑的。

The conversion float to bool is the same as float != 0. However, strict comparing two floating points is not always as you'd expect, due to precision. 从float到bool的转换与float!= 0相同。但是,由于精度的原因,严格比较两个浮点并不总是如您所愿。

A float will be converted to false if its == 0.0f, but beware of the precision! 如果浮点数== 0.0f,则浮点数将转换为false ,但要注意精度! Otherwise it will be converted to true -- it will be also true if its not exacly 0.0f! 否则,将被转换为true -这也将是true ,如果它不是exacly 0.0F! Inifinity will also be converted to true . Inifinity也将转换为true As David Thornley mentioned, your example is very bad code. 正如David Thornley所提到的,您的示例是非常糟糕的代码。

I think it would be better to use isnan() . 我认为使用isnan()会更好。

isnan() returns true if f is not-a-number. 如果f不是数字,则isnan()返回true。 But it will return true for eg 0.0 ... 但是它将返回true,例如0.0 ...

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

as mentioned that will not catch the case where f is 0.0 - or very close to it. 如前所述,这将无法解决f为0.0或非常接近f的情况。

If you need this you could check with: 如果您需要,可以通过以下方式进行检查:

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

EDIT: here an improved example including a test driver: 编辑:这是一个改进的示例,其中包括测试驱动程序:

#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

我通常会

return x != 0;

Assuming DoCalculation(x) returns infinity() for non positive values of x then for positive values of x function(x) is true for non-zero values of DoCalculation() and false otherwise. 假设对于x的非正值,DoCalculation(x)返回infinity(),那么对于x的正值,对于DoCalculation()的非零值,则function(x)为true,否则为false。 So function(x) is to determine if DoCalculation(x) is zero or not. 因此,函数(x)将确定DoCalculation(x)是否为零。 I would rename function(x) to IsDoCalculationNonzero(x). 我会将function(x)重命名为IsDoCalculationNonzero(x)。

This seems pretty straightforward. 这似乎很简单。 Remember that the only states recognized for bool is zero or non-zero. 请记住,布尔的唯一状态是零或非零。 So this code: 所以这段代码:

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

Would evaluate as follows: 评估如下:

if x > 0 : return f. 如果x> 0:返回f。 If f == 0.0F then it will return false. 如果f == 0.0F,则它将返回false。 Otherwise it will return true. 否则它将返回true。 As others have mentioned, precision issues may give a false true, but if it's working then I 'd say not... 正如其他人提到的那样,精度问题可能会给出错误的true,但是如果它起作用了,那么我会说不...

If x <= 0 : return infinity() which is ... an odd case. 如果x <= 0:返回infinity(),这是一种奇怪的情况。 However, infinity() != 0 -- therefor this will return true. 但是,infinity()!= 0-因此将返回true。 (Reference: http://msdn.microsoft.com/en-us/library/85084kd6.aspx ) (参考: http : //msdn.microsoft.com/en-us/library/85084kd6.aspx

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

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