IT박스

C / C ++의 최소 double 값

itboxs 2020. 10. 13. 07:35
반응형

C / C ++의 최소 double 값


C (++) 프로그램에서 가장 작은 음수 값 (예 : 음의 무한대 사용)을 나타내는 표준 및 / 또는 이식 가능한 방법이 있습니까?

float.h의 DBL_MIN은 가장 작은 양수 입니다.


-DBL_MAX ANSI C에서 , float.h에 정의되어 있습니다.


부동 소수점 숫자 (IEEE 754)는 대칭이므로 가장 큰 값 ( DBL_MAX또는 numeric_limits<double>::max())을 나타낼 수 있는 경우 마이너스 기호를 앞에 추가하면됩니다.

다음은 멋진 방법입니다.

double f;
(*((long long*)&f))= ~(1LL<<52);

C에서는

#include <float.h>

const double lowest_double = -DBL_MAX;

C ++ pre-11에서는

#include <limits>

const double lowest_double = -std::numeric_limits<double>::max();

C ++ 11 이상에서는

#include <limits>

constexpr double lowest_double = std::numeric_limits<double>::lowest();

이 시도:

-1 * numeric_limits<double>::max()

참고: numeric_limits

이 클래스는 각 기본 유형에 특화되어 있으며 해당 멤버는 컴파일되는 특정 플랫폼에서 유형이 갖는 속성을 정의하는 다른 값으로 반환되거나 설정됩니다.


실제 무한대 또는 최소 유한 값을 찾고 있습니까? 전자의 경우

-numeric_limits<double>::infinity()

다음 경우에만 작동합니다.

numeric_limits<double>::has_infinity

그렇지 않으면

numeric_limits<double>::lowest()

C ++ 11에 도입되었습니다.

lowest()사용할 수없는 경우 다음 으로 돌아갈 수 있습니다.

-numeric_limits<double>::max()

lowest()원칙적으로 다를 수 있지만 일반적으로 실제로는 그렇지 않습니다.


진정으로 이식 가능한 C ++ 솔루션

C ++ 11에서와 같이 numeric_limits<double>::lowest(). 표준에 따르면 원하는 것을 정확하게 반환합니다.

다른 유한 값 y가없는 유한 값 x입니다 y < x. 여기서 .
모든 전문 분야에서 의미가 is_bounded != false있습니다.

온라인 데모


여기에 이식성이없는 C ++ 답변이 많이 있습니다!

에 대한 많은 답변이 있습니다 -std::numeric_limits<double>::max().

다행히도 대부분의 경우 잘 작동합니다. 부동 소수점 인코딩 체계는 가수와 지수의 숫자를 분해하며 대부분 (예 : 인기있는 IEEE-754 )은 가수에 속하지 않는 고유 한 부호 비트를 사용합니다. 이렇게하면 부호를 뒤집어 가장 작은 음수에서 가장 큰 양수를 변환 할 수 있습니다.

여기에 이미지 설명 입력

왜 휴대용이 아닌가?

표준은 부동 소수점 표준을 부과하지 않습니다.

I agree that my argument is a little bit theoretic, but suppose that some excentric compiler maker would use a revolutionary encoding scheme with a mantissa encoded in some variations of a two's complement. Two's complement encoding are not symmetric. for example for a signed 8 bit char the maximum positive is 127, but the minimum negative is -128. So we could imagine some floating point encoding show similar asymmetric behavior.

I'm not aware of any encoding scheme like that, but the point is that the standard doesn't guarantee that the sign flipping yields the intended result. So this popular answer (sorry guys !) can't be considered as fully portable standard solution ! /* at least not if you didn't assert that numeric_limits<double>::is_iec559 is true */


- std::numeric_limits<double>::max()

should work just fine

Numeric limits


The original question concerns infinity. So, why not use

#define Infinity  ((double)(42 / 0.0))

according to the IEEE definition? You can negate that of course.


Is there a standard and/or portable way to represent the smallest negative value (e.g. to use negative infinity) in a C(++) program?

C approach.

Many implementations support +/- infinities, so the most negative double value is -INFINITY.

#include <math.h>
double most_negative = -INFINITY;

Is there a standard and/or portable way ....?

Now we need to also consider other cases:

  • No infinities

Simply -DBL_MAX.

  • Only an unsigned infinity.

I'd expect in this case, OP would prefer -DBL_MAX.

  • De-normal values greater in magnitude than DBL_MAX.

This is an unusual case, likely outside OP's concern. When double is encoded as a pair of a floating points to achieve desired range/precession, (see double-double) there exist a maximum normal double and perhaps a greater de-normal one. I have seen debate if DBL_MAX should refer to the greatest normal, of the greatest of both.

Fortunately this paired approach usually includes an -infinity, so the most negative value remains -INFINITY.


For more portability, code can go down the route

// HUGE_VAL is designed to be infinity or DBL_MAX (when infinites are not implemented)
// .. yet is problematic with unsigned infinity.
double most_negative1 = -HUGE_VAL;  

// Fairly portable, unless system does not understand "INF"
double most_negative2 = strtod("-INF", (char **) NULL);

// Pragmatic
double most_negative3 = strtod("-1.0e999999999", (char **) NULL);

// Somewhat time-consuming
double most_negative4 = pow(-DBL_MAX, 0xFFFF /* odd value */);

// My suggestion
double most_negative5 = (-DBL_MAX)*DBL_MAX;

If you do not have float exceptions enabled (which you shouldn't imho), you can simply say:

double neg_inf = -1/0.0;

This yields negative infinity. If you need a float, you can either cast the result

float neg_inf = (float)-1/0.0;

or use single precision arithmetic

float neg_inf = -1.0f/0.0f;

결과는 항상 동일하며 단 정밀도와 배정 밀도 모두에서 음의 무한대를 정확히 하나만 표현하며 예상대로 서로 변환됩니다.

참고 URL : https://stackoverflow.com/questions/1153548/minimum-double-value-in-cc

반응형