2009-12-28 5 views
1

제 3 자 코드를보고 있는데 한 줄로 무엇을하고 있는지 정확히 알 수 없습니다. 내가 정확한 코드를 게시 할 수 있지만의 라인을 따라입니다 : float- 변환하는 방법에 대한C++ float to bool 변환

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

이 분명 컴파일러에서 경고를 던졌습니다> 부울하지만 실제 행동은 무엇을 할 것인가? Visual C++에서 부동 소수점을 bool로 변환하는 방법은 무엇입니까? 적어도 그 불쾌한 무한을 대체 할 수 있어야합니다 ...

+3

저에게 나쁜 코드처럼 보입니다. 'x <= 0.0' 일 때 왜 계산을합니까? 왜 둘 모두가'true'로 변환 되었기 때문에 1.0이 아닌 무한대의 표현식을 작성해야하는 이유는 무엇입니까? 부동 소수점의 동등성 ('float'에서'bool' 으로의 변환) 때문에'x> 0.0'과'f == 0.0 '이라면 x에서 무언가를 계산하고,'abs (f) <엡실론') 불확실한가요? 거기에 나쁜 코드가 있다고 생각합니다. –

+0

"정확한"코드를 게시 할 수 없습니까? 함수 (x)의 "정확한"이름은 무엇입니까? – fupsduck

+1

무슨 차이가 있습니까? 라이센스 제한으로 인해 코드를 게시 할 수 없으며 이에 상응하는 정도로 유사합니다. –

답변

22

실수라고 생각합니다. 이 함수는 float을 반환해야합니다. 이것은 나에게 논리적 인 것처럼 보인다.

float! = bool 로의 변환 float는 float! = 0과 같습니다. 그러나 정밀도로 인해 두 부동 소수점을 엄격하게 비교하는 것이 항상 기대했던 것과 다를 수 있습니다.

+0

별로 도움이되지 않습니다. 이것은 제 3 자 라이브러리에 있습니다. 함수 호출을 추적 할 시간이 없으며 모든 것을 알아낼 수 있습니다 ... float 변환 규칙이 무엇인지, 특히 무한대인지 알고 싶습니다. –

+0

무한대 *는 "true"로 변환됩니다. 0이 아니기 때문에 오타가 강하게 냄새가납니다. –

+11

어떻게 도움이되지 않습니까? 그는 당신의 질문에 대답했습니다 : "부화 된 부유물은 부유물과 같습니다! = 0". 무한대가 0입니까? 그렇지 않으면 float가 true로 변환됩니다. – jalf

0

나는 일반적으로

return x != 0; 
2

은 플로트가 == 0.0f를하는 경우 false로 변환하지만, 정밀 조심한다 할! 그렇지 않으면 true으로 변환됩니다. true (해당하지 않을 경우) exacly 0.0f! 또한 Inifinity는 true으로 변환됩니다. 데이비드 쏜리 (David Thornley)가 언급했듯이, 당신의 예는 매우 나쁜 코드입니다.

0

isnan()을 사용하는 것이 더 좋을 것이라고 생각합니다.

isnan()은 f가 숫자가 아닌 경우 true를 반환합니다. 그러나 예를 들어 0.0 ...

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 

0

DoCalculation을 (가정 x)는 x의 양수가 아닌 값에 대해 infinity()를 반환하고 x가 양수이면 (x) function이 0이 아닌 경우 true입니다. doCalculation()의 값을 반환하고 그렇지 않으면 false입니다. 따라서 함수 (x)는 DoCalculation (x)이 0인지 아닌지를 결정하는 것입니다. 나는 함수 (x)를 IsDoCalculationNonzero (x)로 이름을 바꿀 것이다.

0

이것은 매우 간단합니다. bool에 대해 인식되는 상태는 0 또는 0이 아닌 것을 기억하십시오. 그래서이 코드를 다음과 같이

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

평가겠습니까 :

0 X>의 경우 : 리턴 바. f == 0.0F의 경우, false를 돌려줍니다. 그렇지 않으면 true를 반환합니다. 다른 사람들이 언급했듯이, 정밀 문제는 거짓 사실을 줄 수 있지만 작동하는 경우 나는 말할 수 없습니다. ...

x < = 0 인 경우 ... 이상한 경우입니다. 그러나 무한대()! = 0 -이 때문에 true를 반환합니다.(참조 : http://msdn.microsoft.com/en-us/library/85084kd6.aspx)