팹을 언제 사용하고 std :: abs를 사용하기에 충분합니까?


100

나는을 사용할 때 absfabs다르게 행동 한다고 가정합니다 math.h. 하지만 cmathand std::abs를 사용할 때는 std::fabs또는 을 사용해야 fabs합니까? 아니면 이것이 정의되지 않았습니까?

답변:


124

C ++에서는 항상 사용하기에 충분합니다 std::abs. 모든 숫자 유형에 대해 오버로드됩니다.

C에서는 abs정수에서만 작동 fabs하며 부동 소수점 값 이 필요 합니다. C ++ (모든 C 라이브러리와 함께)에서 사용할 수 있지만 사용할 필요가 없습니다.


모든 플랫폼에서이 경우가 해당됩니까? Esp. Windows 및 Mac OS X? 아니면 적어도 C ++ 표준에 있습니까?
math

3
@brubelsabs : 네. C ++에는 함수 오버로딩이 있으므로 C ++에서 별도의 fabs 함수가 필요하지 않습니다 (abs는 수많은 유형에 대해 정의 될 수 있으며 C ++에 있음). 또한 표준에 의해 보장됩니다. 물론 10 년이 넘은 오래된 컴파일러를 찾아 보면 지원하지 않는 컴파일러를 찾을 수 있습니다.
stinky472 2010-06-25

1
그것은 그래서 Windows 및 Mac OS X의 제 26.5 포함 괜찮은 컴파일러와 모든 플랫폼의 경우 년대에 더하여, 그 말한다, C ++ 표준에서의 intC 라이브러리의 버전에 대한 과부하가 long, float, doublelong double. 26.2.7 절은 complex.
Mike Seymour

6
을 잊어 버리고을 std::사용 abs하면 코드가 Windows에서는 예상대로 작동하지만 intLinux에서는 디버그하기가 매우 어려울 수있는 버전을 사용합니다 .
Adversus

" 모든 숫자 유형"[인용 필요]. int, long, long long, std :: intmax_t, float, double, long double을 볼 수 있습니다. 내가 볼 수있는 짧은 버전이나 문자 버전 (또는 서명되지 않은 버전)이 없습니다.
user673679

23

fabsfor doubleand floatarguments 를 사용 하는 것은 여전히 ​​괜찮습니다 . 그것을 보장하기 때문에 나는이 선호하는 내가 실수로 제거하면 std::오프를 abs동작 점 입력을 부동 동일하게 유지.

abs대신을 사용 하는 내 실수로 인해이 문제를 디버깅하는 데 10 분을 보냈습니다 std::abs. 나는 using namespace std;추론 할 것이라고 std::abs생각했지만 그렇지 않고 대신 C 버전을 사용했습니다.

어쨌든 의도를 명확하게 문서화하는 방법으로 부동 소수점 입력 fabs대신 사용 하는 것이 좋다고 생각합니다 abs.


2
이상 하네. 당신의 전화는 모호 했어야했는데 (따라서 오류) 맞나요?
Nick

float에 fabsf를 ​​사용해야하지 않습니까? 그래서 나는 그들이 동일하다고 생각하지 않습니다.
Nick

Android NDK g ++에주의하세요. std :: abs () 대신 c abs () 함수도 사용합니다. 그러나 Visual Studio C ++ 컴파일러에서는 abs가 항상 std :: abs ()를 가리 킵니다.
southerton 2015

@Nick, 내가 당신과 동의 생각 : 나는 나를에 대한 앨런 튜링 (Alan Turing), 즉의 동작을 취득하지 않는 것 과부하가 std::abs항상 호출 될 것으로 보인다 (그리고 아닌 C-버전 abs) 때 부르심 abs만큼 using namespace std;상기 explicated한다 처음. 이것이 컴파일러에 특정한 것인지는 모르겠습니다.
MaviPranav

@Nick은 일치하는 함수 이름이 있으므로 오류가 아닙니다. 어느 것이 선택 될지 정의 된 구현입니다.
Pato Sandaña

11

std::fabs부동 소수점 입력을 명시 적으로 권장 하는 또 다른 이유가 있습니다.

당신이 <cmath> 포함하는 것을 잊지 경우, 당신은 std::abs(my_float_num)할 수 있습니다 std::abs(int)대신 std::abs(float). 눈치 채기 어렵습니다.


1

"abs"와 "fabs"는 모호한 오버로드 메시지없이 변환 될 수있는 C ++ float 유형에 대해서만 동일합니다.

g ++ (g ++-7)을 사용하고 있습니다. 템플릿 사용과 함께 특히 mpreal을 사용할 때 하드 "모호한 과부하"메시지가있는 경우 abs(static_cast<T>(x))가 있습니다. 항상 문제가 해결되지는 않습니다. 복근이 모호하면 팹이 예상대로 작동 할 가능성이 있습니다. sqrt의 경우 그러한 간단한 탈출구를 찾지 못했습니다.

몇 주 이후로 저는 "기존 문제가 아닌"C ++에서 고군분투하고 있습니다. 이전보다 더 많은 템플릿 사용을 위해 이전 C ++ 프로그램을 C ++ 14로 업데이트하고 있습니다. 종종 동일한 템플릿 매개 변수가 실제 표준 float 또는 복합 유형 또는 클래스 유형일 수 있습니다. 왜 그래도 long double은 다른 유형보다 다소 합리적입니다. 모두 작동하고 있었고 전에 mpreal을 포함 시켰습니다. 그런 다음 기본 float 유형을 mpreal로 설정하고 구문 오류가 많이 발생했습니다. 그것은 예를 들어 abs 및 sqrt에 대한 수천 개의 모호한 과부하를 제공하여 다른 솔루션을 요구했습니다. 일부는 오버로드 된 도움말 기능이 필요했지만 템플릿 외부에있었습니다. 0.0L 및 1.0L의 천 사용을 개별적으로 Zero 또는 One 또는 type_cast를 사용하는 정확한 상수 유형으로 대체해야했습니다. 모호함으로 인해 자동 변환 정의가 불가능했습니다.

5 월까지는 기존의 암시 적 변환이 매우 훌륭하다는 것을 알았습니다. 그러나 그것이없는 것이 훨씬 더 간단 할 것이고, 다른 표준 상수 유형에 안전한 명시 적 type_cast를 가진 상수를 typeave하는 것이 훨씬 더 간단 할 것입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.