산술 연산에 의해 전파 될 값을 찾고있는 경우 -ffast-math
과 함께 NaN
을 계속 사용할 수 있습니다. 문제는 다른 곳에서 발생합니다. -ffast-math
을 사용하면 최적화로 인해 일부 연산을 계산에서 제거 할 수 있으며 따라서 NaN
또는 다른 값이 전파 될 수 있음을 보장 할 방법이 없습니다.
예를 들어, 다음, -ffast-math
세트, n
에 0.0
를 작성 하드의 원인이되고 그것으로부터 보호 할 수 n
에 대한 특수 값은 없습니다. 당신이 할 수있는
float n = NAN;
n *= 0.0;
한 가지, Shafik Yaghmour 말했듯이 -ffast-math
와 -fno-finite-math-only -ftrapping-math
을 사용하는 것입니다. 그리고 다른 하나는, 나쁜 가치를 기대하는 곳이 몇 군데 밖에 없다면, 그 지점에 정확하게 시험을 치는 것으로 스스로 확인할 수 있습니다.
내가 정말로 생각할 수있는 마지막 옵션 - 실제로 최적화가 절실히 필요한 경우 - 수동으로 NaN
(및 아마도 inf
) 값을 주입하고 이것이 전파되는 시간을 확인하는 것입니다. 그런 다음 전파 전파가 중지되는 곳에서 NaN
(inf
)을 테스트합니다. - 이것은 안전하지 않은 방법입니다. 왜냐하면 나는 백분율이 아니기 때문에 -ffast-math
은 조건부 동작 흐름을 포함 할 수 있습니다. 가능한 경우 상당한 기회가 있습니다.이 솔루션은 유효하지 않습니다. 따라서 위험하고 선택하면 계산의 모든 가지를 다루는 매우 무거운 테스트가 필요합니다.
일반적으로 나는 오히려 마지막 해결책에 반대 할 것이지만, 실제로는 기회가 있습니다. NaN
(inf
) 값은 전체 계산 또는 거의 전체적으로 전파되므로 값을 구할 수 있습니다. 따라서 위험을 감수하고 싶을 수 있습니다.
inf
점검하는 것 Shafik Yaghmour 말했듯이
inline int isnan(float f)
{
union { float f; uint32_t x; } u = { f };
return (u.x << 1) > 0xff000000u;
}
와 함께, 당신이 할 수있는 -ffast-math
와 NaN
에 대한 확인 및
inline int isnan(double d)
{
union { double d; uint64_t x; } u = { d };
return (u.x << 1) > 0xff70000000000000ull;
}
에 대한 double
inline int isinf(float f)
{
union { float f; uint32_t x; } u = { f };
return (u.x << 1) == 0xff000000u;
}
inline int isinf(double d)
{
union { double d; uint64_t x; } u = { d };
return (u.x << 1) == 0xff70000000000000ull;
}
,
isnan
과 isinf
을 병합 할 수도 있습니다.
이 스레드가 도움이 될 수 있습니다. [Mingw32 std :: isnan with -ffast-math] (http://stackoverflow.com/questions/7263404/mingw32-stdisnan-with-ffast-math) –
@ShafikYaghmour 감사합니다. 도움이됩니다. – stgtscc
'-fno-finite-math-only -ftrapping-math' 옵션을 사용할 수도 있습니다. http://lua-users.org/lists/lua-l/2009-04/msg00091.html –