2012-06-22 10 views
3

C에서 "정상"실수 TREAL x을 고려 ++ (무한하지 비정규하지 NaN이 /) (TREAL = float, double, long double)
되는 부동 소수점에서 이전 및 다음 x을 찾을 수있는 좋은 솔루션을 다음 관점?C++ 다음 float 숫자로 numeric_limits/엡실론?

TREAL xprev = (((TREAL)(1.)) - std::numeric_limits<TREAL>::epsilon()) * x; 
TREAL xnext = (((TREAL)(1.)) + std::numeric_limits<TREAL>::epsilon()) * x; 

고맙습니다.

+2

x prev next! = x? – Dani

+0

가수를 증가 시키면 (x + 1)이 아니라 값을 원한다는 말입니까? – Skizz

+0

네, x + 1 x +/- 엡실론을 원하지 않습니다. (가능한 정밀도 문제를 가지고있는 경계를 확인하는 것입니다.) – Vincent

답변

10

다음에 C99 및 C++ 11이 있고, nextafter1 및 nextafterf는 <math.h><cmath>에서 기능한다. 기본 산술과 엡실론으로 구현하면 반올림을 고려해야하므로 지루할 수 있습니다. 이진 표현에 대한 작업이 더 쉬울 지 모르지만 부호 및 크기 표현의 효과와 -0.0의 존재에 대해 궁금합니다 (필요한 내용은 Fred's answer 참조). 다음 부동 소수점 숫자를 얻기

5

바이너리 수준에서 훨씬 쉽게이 만 될 일이 부동 소수점 숫자는 "오름차순"저장하는 시스템을 위해 작동 물론

float next(float f) 
{ 
    unsigned x; 
    memcpy(&x, &f, 4); 
    ++x; 
    memcpy(&f, &x, 4); 
    return f; 
} 

IEEE754의 경우.

음수는 음의 무한대로 이동합니다. 대신 0으로 이동 하시겠습니까? 이것을 사용하십시오 :

float next(float f) 
{ 
    int x; 
    memcpy(&x, &f, 4); 
    x += x >> 31 | 1; // this will add 1 for positive f and -1 for negative f 
    memcpy(&f, &x, 4); 
    return f; 
} 
+0

적어도 음수는 작동하지 않습니다. – AProgrammer

+0

@AProgrammer fixed – fredoverflow

+0

은 -0에 대해 작동하지 않습니다 (NaN을 제공하고, nextafterf는 1.4012984643e-45를 제공합니다). – AProgrammer

1

아니요, "연속적인"부동 소수점 값 사이의 비율이 일정하지 않습니다. 이 접근법은 일부를 놓칠 수도 있고, xnext == x 지점에 머물러있을 수도 있습니다.

  • 는 가수와 지수를 추출;에

    다음 큰 값으로 하나 개의 값에서 이동하려면, 당신은 할 것
  • 가수가 증가합니다.
  • 오버 플로우 된 경우 다시 설정하고 지수를 증가시킵니다.
  • 지수 및 가수의 값을 재구성합니다.

세부 사항은 상당히 까다롭기 때문에 아마도 부동 소수점 표현에 대한 지식이 필요할 것입니다.

그러나 IEEE와 비슷한 표현을 가정하면 비트 패턴을 충분히 큰 정수로 재 해석하고 해당 정수를 증가시킴으로써이를 달성 할 수 있습니다. 그러면 우리가 원하는대로 넘침이 지수로 이동하면서 가수가 증가합니다.