我正在查看一些第三方代码,并且我不确定一行正在做什么。我无法发布确切的代码,但它是:
bool function(float x)
{
float f = doCalculation(x);
return x > 0 ? f : std::numeric_limits<float>::infinity();
}
这显然会引发编译器关于转换float-&gt; bool的警告,但实际行为是什么? Visual C ++如何将浮动转换为bools?至少我应该能够取代那令人讨厌的无限......
答案 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)