2014-12-06 1 views
4

정확히 하나의 부동 소수점 수에서 다음 수로 루프하려고합니다. 말하자면, 정확히 표현할 수있는 IEEE754 번호 인 std::numeric_limits<float>::epsilon()에서 1으로 루프를 만들어야합니다. 내 코드는 다음과 같습니다 시간 beacuse 무한 루프부동 소수점 표현의 정확한 표현을 반복하는 방법은 무엇입니까?

using nld = std::numeric_limits<float>; 
auto h = nld::epsilon(); 
for (; h < 1; h = std::nextafter(h, 1)) { 
    std::cerr << "h: " << h << std::endl; 
} 

정확하게 표현할 수있는, 그래서 nextafter이 그것을 반환 유지합니다. 또한 루프에서 기계 엡실론을 h에 추가하면 절단되지 않습니다. 부동 소수점 숫자는 균등하지 않습니다. IEEE754 숫자의 정확한 표현을 어떻게 반복합니까?

not equally spaced 문제는 여기에 자신을 제시 : 정수 notmal 긍정적 인 수레 위해 작동 나를

+1

'nextafter'는 꼭해야 할 일입니다. h가 정확히 표현할 수 있다는 의견을 이해할 수 없습니다. 물론 변수에 저장된 모든 * 부동 소수점 숫자는 정확하게 표현할 수 있습니다. 당신의 시스템은'nextafter'의'float' 과부하가 부족합니다, 즉'float'에서 표현할 수없는 * 값을 반환 할 수있는'double' 구현을 의미합니까? 그렇다면'nextafterf'를 시도해 볼 수 있습니다. – hvd

+0

@hvd nextafter (h, 1)가 계속 나를 위해'h '를 반환합니다. 나는 그것을 nextafterf에 강제로 넣으려고 할 것이다. – alisianoi

+0

@hvd 오, 맞다. 플로트로 작업해야 할 때,'nextafterf' (f가 플로팅 포인트 넘버를 반복한다. 밝혀 지, 나의'nextafter는 실제로'double'이었다, 고마워! – alisianoi

답변

2

:

nextafter과의 접근 방식은 정확하게 당신이 일을해야하는 것이다. 그러나 예기치 않은 결과를 초래할 수있는 몇 가지 합병증이 있습니다.

인용 cppreference std::nextafter :

float nextafter(float from, float to); (1) (이후 C++ 11)
double nextafter(double from, double to); (2)
long double nextafter(long double from, long double to); (3) (이후 C++ 11 (C++ 보낸 11) 오버로드)
Promoted nextafter(Arithmetic from, Arithmetic to); (4) (이후 C++ 11)

...

4) 집합 (1-3)에 포함되지 않은 산술 유형의 모든 인수 조합에 대한 함수 템플리트. 인수에 정수 유형이 있으면 double으로 3 스트됩니다. 인수가 long double이면 반환 유형 Promotedlong double이고, 그렇지 않으면 반환 유형은 항상 double입니다. 당신의 to 이후

유형 int, 당신은 double의 반환 유형, 과부하 버전 4를 얻을 1입니다. 이제 부동 소수점 f, (float)nextafter((double)f, 1)이 원래 f과 정확히 일치 할 가능성이 있습니다. double 유형의 다음 표현 가능 숫자는 float에 표시 할 수 없으며 float으로의 전환이 반올림 한 것으로 보입니다.

float을 반환하는 유일한 과부하는 tofloat 인 유형입니다. 해당 과부하를 사용하려면 1 대신 1.0f을 사용하십시오.

0

그들을 치료 2 인쇄를 계속

using nld = std::numeric_limits<float>; 
auto h = nld::epsilon(); 
for (; h < 4; h += nld::epsilon()) { 
    if (h = h + nld::epsilon()) { 
     std::cerr << "h: " << h << std::endl; 
    } 
} 

는 부정적인 수레가 잘못된 방향으로 단계, 그리고 것 비정규직과 제로는 특별한 경우 일 수 있습니다.

예 : 양 정상 수레 :

float nextfloat(float in) 
{ 
    union { float f; uint32_t i; } a; 
    a.f=in; 
    a.i++; 
    return(a.f); 
} 

이는 여기에 내가 플로트와 uint32_t 쌍, 정수와 같은 엔디 언과 크기를 갖는 수레에 의존하지만, 두 번에 대한 동일한 기능을 수행 할 수 있으며, uint64_t ... 이것은 실제로 정의되지 않은 동작의 클래스 일 수 있습니다.이 동작을 테스트하는 것은 아마도 빌드 프로세스의 일부분이어야합니다. 코멘트 당

+0

@hvd 그가 정상적인 플로트이기 때문에 엡실론에서 시작한다면, 그는 1의 범위와 단조 로움을 얻게 될 것입니다. – Jasen

+0

오, 더 정확하게 읽으십시오. 당신이 당신의 대답에서 가정 한 대부분의 가정을 보았습니다. 구현시와 코드를 사용할 수있는 모든면에서, 코드는 가정이 유지되는 한 계속 작동합니다. 나는 그것이 좋은 일반적인 해결책이라고 생각하지 않지만, 실제로 전형적인 구현에서 놀랍도록 가깝다. – hvd

관련 문제