1.0이 아닌 1.0에 가장 가까운 두 배는 얼마입니까? 빼는 것입니다. IEEE754 부동

1.0에 가장 가깝지만 실제로 1.0이 아닌 double을 프로그래밍 방식으로 얻을 수있는 방법이 있습니까?

이를 수행하는 한 가지 해키 방법은 double을 동일한 크기의 정수로 memcpy 한 다음 1을 빼는 것입니다. IEEE754 부동 소수점 형식이 작동하는 방식은 분수 부분을 모두 0 (1.000000000000)에서 모두 1 (1.111111111111)로 변경하면서 지수를 1만큼 감소시킵니다. 그러나 정수가 리틀 엔디안으로 저장되고 부동 소수점이 빅 엔디안으로 저장되는 기계가 있으므로 항상 작동하지는 않습니다.



답변

C 및 C ++에서 다음은 1.0에 가장 가까운 값을 제공합니다.

#include <limits.h>

double closest_to_1 = 1.0 - DBL_EPSILON/FLT_RADIX;

그러나 이후 버전의 C ++에서는 limits.h더 이상 사용되지 않고 climits. 그러나 어쨌든 C ++ 특정 코드를 사용하는 경우

#include <limits>

typedef std::numeric_limits<double> lim_dbl;
double closest_to_1 = 1.0 - lim_dbl::epsilon()/lim_dbl::radix;

그리고 Jarod42가 그의 대답에 쓴 것처럼 C99 또는 C ++ 11 이후로 다음을 사용할 수도 있습니다 nextafter.

#include <math.h>

double closest_to_1 = nextafter(1.0, 0.0);

물론 C ++에서는 대신 포함 cmath하고 사용할 수 있습니다 (나중 C ++ 버전의 경우) std::nextafter.


답변

C ++ 11부터 nextafter주어진 방향으로 다음 표현 가능한 값을 얻기 위해 사용할 수 있습니다 .

std::nextafter(1., 0.); // 0.99999999999999989
std::nextafter(1., 2.); // 1.0000000000000002

데모


답변

C에서는 다음을 사용할 수 있습니다.

#include <float.h>
...
double value = 1.0+DBL_EPSILON;

DBL_EPSILON 1과 표현 가능한 1보다 큰 최소값의 차이입니다.

실제 값을 보려면 여러 자리로 인쇄해야합니다.

내 플랫폼에서 printf("%.16lf",1.0+DBL_EPSILON)제공합니다 1.0000000000000002.


답변

C ++에서는 이것을 사용할 수도 있습니다.

1 + std::numeric_limits<double>::epsilon()


답변