簡體   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