2017-05-12 14 views
1

I가 (매우 효율적인 아니지만) 다음, 비교적 간단는 fabs 기능의 구현 :이 팹 구현은 NaN에 유효합니까?

double fabs(double x) { 
    if (x == 0.0) return 0.0; // deals with both 0.0 and -0.0. 
    if (x > 0.0) return x; // deals with ]0.0 .. +inf], but "(NaN > 0.0)" is false 
    return -x; // deals with [-inf .. 0.0[, and NaNs 
} 

유일한 "잡았다"나는 긍정적 인 NaN이 그것을, 주어진 사실이다이 구현 발견 부의 값을 돌려줍니다. 그러나 표준에서 아무것도 허용되지 않는다고 말할 수는 없습니다.

은 특히, 여기에 내가 무엇을 발견 :

§7.12.7 :

설명

는 팹 함수는 부동 소수점 숫자 x의 절대 값을 계산한다.

반품

fabs 함수는 | x |를 반환합니다.

이것은 숫자가 아닌 NaN과 같은 제약 조건을 부과하지 않습니다.

F.10.4.2 :

팹 기능

- 팹 (± 0) 0을 반환합니다.

- fabs (± ∞)는 + ∞를 반환합니다.

반환 값은 정확하고 현재 반올림 방향 모드와 독립적입니다.

다시 말해서 NaN에 대한 제약이 없습니다.

F.10, 항목 11 : NaN의 인수와 함께

기능은 NaN의 결과를 반환하고, 그렇지 않으면 명시된 경우를 제외하고 부동 소수점 예외를 인상하지 않습니다.

서명의 제약이 없습니다.

특히, signbit(fabs(x))은 부동 소수점 x에 대해 0을 반환해야한다는 사실에 대한 언급이 없습니다. 이는 본질적으로 구현이 위반하는 것입니다.

그러나 이모 란 티아 율리스 변리사는이 구현이 적합 함을 확신하고 싶습니다. 내가 찾은 libc 구현 (glibc, musl)은 모든 종류의 저수준 비트 트릭이나 컴파일러 내장 함수를 효율적으로 사용하므로이 경우 많은 정보를 제공하지 않는다.

"예기치 않은"매너 (예 : MSVC)를 사용하는 경우 컴파일러 자체에서하는 것보다 표준 자체가 요구하는 것에 더 관심이 많기 때문에 명확히하기 위해 language-lawyer 태그를 추가했습니다. @WeatherVane이보고 한 바와 같이 -nan의 빼기 부호), 표준이 너무 엄격하지 않음을 확인할 수 있습니다 (그러나 MSVC는 표준 준수의 좋은 예가 아닙니다 ...).

+1

'NaN'은 "숫자가 아닙니다"라고 가정하면 음수 "숫자가 아닙니다"는 거의 동일한 양의 값입니다. 나는 NaN 부호의 의미가 있다고 생각하지 않는다. [this] (https://en.wikipedia.org/wiki/IEEE_754-1985#NaN)에서 'NaN'은 부호를 가질 수 있습니다. –

+0

부동 소수점에 대한 위키 백과 페이지는 ± NaN, NaN 만 언급하지 않지만 ± 0 및 ± 무한을 구별합니다. 그래서 전달 된 값이'NaN'이면 반환 할 수있는 것은'NaN'입니다. –

+0

... MSVC는 부호 비트에 따라'nan' 또는'-nan'을 인쇄합니다. –

답변

2

C 표준은 부속서 F (선택 사항 임)를 제외하고는 부동 소수점 동작을 지정하는 데 약하며 부속서 F를 채택하지 않은 C 표준을 준수하는 C 구현은 사용자가 지시하는대로 동작 할 수 있습니다.

그러나 품질 구현은 적어도 IEEE 754-2008 (C 표준 부속서 F에서 언급 한 IEC 60559와 동일)을 준수하려고합니다. IEEE 754-2008은 5.5.1 절에서 부동 소수점 피연산자 (NaN 포함)를 무효화하면 부호 비트가 변경된다고 말합니다.

+0

감사! * abs (x)는 부동 소수점 피연산자 x를 동일한 형식으로 대상에 복사하여 부호 비트를 0 (양수)으로 설정합니다. * 따라서, 5.5.1에서 발췌 한 내용이 제 경우에 직접 적용됩니다. 내 질문에 대한 답변을 요약하면 다음과 같습니다. * 네, 유효한 wrt입니다. C 표준에 맞추지 만, (선택 사항) IEEE 754-2008 표준 *에는 따르지 않습니다. – anol