C / C ++의 최소 double 값


92

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

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


4
나는 -DBL_MAX에 갈 것입니다. 그러나 이것이 그렇지 않은 기술적 이유가있을 것입니다. :-)

4
@Neil, 더는이 개 보완 정수처럼,이 아니에요하지 않습니다
포트란

나는 표준에서 부동 소수점 유형의 범위가 0을 중심으로 대칭이어야한다고 말하는 것을 아직 보지 못했습니다. 그러나 limits.h 및 <limits>의 상수는 C 및 C ++ 표준이 모두 예상하고 있음을 시사합니다.
Steve Jessop

4
실제로 float.h의 DBL_MIN은 가장 작은 양의 정규화 된 숫자입니다. 더 작은 숫자가 있습니다.
fdermishin 2013 년

1
@fortran : IEEE 754 FP는 부호 비트를 사용하고 확실히 요즘 대부분의 FP 하드웨어는 IEEE 754입니다. 그러나 C와 C ++는 비 IEEE 754 FP 하드웨어를 지원하므로 언어가 -DBL_MAX를 보장하는지 여부에 대한 질문이 열려 있습니다. 표현 가능한 최소값과 같아야합니다.
j_random_hacker

답변:


135

-DBL_MAX float.h에 정의 된 ANSI C 에서.


이것은 대부분의 표준 및 휴대용 보인다

내 -1에 대한 설명은 다음과 같습니다. -DBL_MAX가 C 또는 C ++ 언어에 의해 표현 가능한 최소값은 말할 것도없고 표현 가능하다는 것을 보증하는 사람 또는 무엇입니까? 대부분의 FP 하드웨어가 IEEE 754를 준수하고이 표현을 사용한다는 사실은 -DBL_MAX가 모든 표준 준수 C 플랫폼에서 작동한다는 것을 의미하지는 않습니다.
j_random_hacker

@j_random_hacker : 포트란의 대답 '아래'를 참조하십시오.
JohnTortugo

3
@j_random_hacker 아주 좋은 점이지만 C 표준은 -DBL_MAX정확하게 표현할 수 있어야 하므로 FP 하드웨어가이를 수행 할 수없는 경우 구현에서이를 해결해야합니다. 5.2.4.2.2 C99 의 부동 유형 <float.h> p2특성에서 부동 소수점 모델을 참조하십시오 (그 이후로 다른 곳으로 이동되었을 수 있음).

2
@j_random_hacker 예,하지만 p2는 e_min과 e_max가 부호 비트와 독립적임을 지정하므로 DBL_MAX정확히 표현할 수있는 (1 − b ^ −p) b ^ e_max, 가장 음의 유한 값은 정확히-(1 − b ^ −p) b ^ e_max, 정확히 -DBL_MAX이므로 부정 DBL_MAX하면 반올림 오류도 발생할 수 없습니다.

70

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

다음은 멋진 방법입니다.

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

6
1 : 부동 소수점 숫자의의 대칭 지적
앤드류 토끼를

4
IEEE 754 부동 소수점을 사용하지 않는 C / C ++ 구현은 어떻습니까?
Steve Jessop

1
-ffast-math에 대한 gcc 매뉴얼은 "Sets -fno-math-errno, -funsafe-math-optimizations, -ffinite-math-only, -fno-rounding-math, -fno-signaling-nans 및 -fcx-limited- range이 옵션은 수학 함수에 대한 IEEE 또는 ISO 규칙 / 사양의 정확한 구현에 의존하는 프로그램에 대해 잘못된 출력을 초래할 수 있기 때문에 -O 옵션에 의해 설정되지 않습니다. 이러한 사양의 보증이 필요하지 않습니다. " 빠른 수학은 일반적인 설정이며 예를 들어 Intel ICC는 기본 설정입니다. 대체로 이것이 나에게 무엇을 의미하는지 확실하지 않습니다. :-)
Will

4
이는 구현이 IEEE 754 산술을 사용하지 않는다는 것을 의미하지만 공정하게 말하면 이러한 옵션은 여전히 ​​IEEE 표현을 사용합니다. 비 IEEE 표현을 사용하는 일부 에뮬레이션 라이브러리를 찾을 수 있습니다. 모든 프로세서가 기본 부동 형식을 가지고있는 것은 아니기 때문입니다 (제조업체에서 제공 한 에뮬레이션 라이브러리에 해당하는 형식을 포함하는 C ABI를 게시 할 수도 있음). 따라서 모든 컴파일러가 하나를 사용할 수있는 것은 아닙니다. "표준 및 / 또는 휴대용"을 요청할 때 의미하는 바에 따라 다르며, 원칙적으로는 휴대용이고 실제로는 휴대용이 있습니다.
Steve Jessop

3
당신이 말하는 것은 IEEE 754에 대해 사실이지만 표준은이 인코딩의 사용을 요구하지 않습니다 (@SteveJessop이 지적했듯이, 실제로 이식성은 원칙적으로 이식성과 동일하지 않습니다).
Christophe

44

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();

min()C ++ 11 이전 에는이 기능을 사용할 수 없었습니까 ? 아니면 다른 값 -max()입니까? en.cppreference.com/w/cpp/types/numeric_limits
Alexis Wilke

5
@Alexis : 링크 한 페이지의 표에서 가장 낮은 3 개의 행 min을 보면 가장 작은 양의 값과 lowest가장 큰 음의 값 을 얻을 수 있습니다 . 예, 끔찍합니다. C ++ 표준 라이브러리의 화려한 세계에 오신 것을 환영합니다 :-P.
rubenvb 2014 년

C의 경우 float.h. limits.h정수를위한 것입니다
Ciprian Tomoiagă

33

이 시도:

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

참고: numeric_limits

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


1
왜 안돼 -numeric_limits<double>::max()?
k06a

4
@ k06a는 문자열이 "max"라고 말하는 긴 표현에서 단일 문자로 표현되는 부정을 가지고 있으면 조만간 누군가를 얻을 것입니다. 설명 변수에 저장하거나 -1 * ...좀 더 명확하게 만드는 데 사용 합니다.
Filip Haglund

20

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

-numeric_limits<double>::infinity()

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

numeric_limits<double>::has_infinity

그렇지 않으면

numeric_limits<double>::lowest()

C ++ 11에서 소개되었습니다.

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

-numeric_limits<double>::max()

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


유한 값과 무한 값의 차이에 +1! 그러나 표준은 대칭 부동 소수점 인코딩을 보장하지 않습니다. 따라서 -numeric_limits<double>::max()실제로 작동하더라도 이론적으로 완전히 이식 할 수는 없습니다.
Christophe

@Christophe : [X] 고정
크리스토프

10

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

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

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

온라인 데모


여기에 많은 이식 불가능한 C ++ 답변이 있습니다!

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

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

여기에 이미지 설명 입력

왜 이것들은 휴대용이 아닌가?

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

나는 내 주장이 약간 이론적이라는 데 동의하지만, 일부 특이한 컴파일러 제작자가 2의 보수의 일부 변형으로 인코딩 된 가수가있는 혁신적인 인코딩 체계를 사용한다고 가정합니다. . 2의 보수 인코딩은 대칭이 아닙니다. 예를 들어 부호있는 8 비트 문자의 경우 최대 양수는 127이지만 최소 음수는 -128입니다. 따라서 일부 부동 소수점 인코딩이 유사한 비대칭 동작을 표시한다고 상상할 수 있습니다.

나는 그런 인코딩 체계를 알지 못하지만, 요점은 표준이 부호 반전이 의도 한 결과를 산출한다고 보장하지 않는다는 것 입니다. 따라서이 인기있는 답변 (죄송합니다!)은 완전히 이식 가능한 표준 솔루션으로 간주 될 수 없습니다! / * 적어도 그것이 numeric_limits<double>::is_iec559사실 이라고 주장하지 않았다면 * /



1

원래 질문은 무한에 관한 것입니다. 그래서 사용하지 않는 이유

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

IEEE 정의에 따르면? 물론 그것을 부정 할 수 있습니다.


좋은 생각 ! 그리고 그것은 작동합니다 . 그러나 경우에만numeric_limits<double>::has_infinity && ! numeric_limits<double>::traps
크리스토프

1

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

C 접근.

많은 구현에서 +/- 무한대를 지원하므로 가장 부정적인 double값은 -INFINITY.

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

표준 및 / 또는 휴대용 방법이 있습니까 ....?

이제 다른 경우도 고려해야합니다.

  • 무한대 없음

간단히 -DBL_MAX.

  • 부호없는 무한대 만 .

이 경우 OP는 -DBL_MAX.

  • 크기가 DBL_MAX.

이것은 OP의 우려를 벗어난 비정상적인 경우입니다. 경우 double(A)의 쌍으로 인코딩 된 부동 소수점 원하는 범위 / 세차 운동을 달성하기 위해, (참조 : 이중 이중 최대 존재) 정상 double 아마도 더 드 통상 하나. 나는 DBL_MAX가장 큰 정상을 언급해야하는지 논쟁을 보았다. 둘 중 가장 .

다행히이 쌍을 이루는 접근 방식은 일반적으로-무한대를 포함하므로 가장 음의 값이 남아 있습니다 -INFINITY.


더 많은 이식성을 위해 코드는 경로를 따라갈 수 있습니다.

// 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;

-1

부동 예외를 활성화하지 않은 경우 (imho해서는 안 됨) 간단히 다음과 같이 말할 수 있습니다.

double neg_inf = -1/0.0;

이것은 음의 무한대를 산출합니다. 플로트가 필요한 경우 결과를 캐스팅 할 수 있습니다.

float neg_inf = (float)-1/0.0;

또는 단 정밀도 산술 사용

float neg_inf = -1.0f/0.0f;

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


그냥 쓰는 대신 왜 이렇게 하시겠습니까-INFINITY
MM

또한 무한대는 존재하거나 존재하지 않을 수 있으며 존재하는 경우 양수와 음수를 구별 할 수 없습니다 (표준 C에서).
MM

많은 컴파일러 및 / 또는 아키텍처에서 C / C ++ 코드는 무한대 및 NaN 값을 전파하는 속도를 늦 춥니 다.
markgalassi

@markgalassi 자세히 살펴보면 상수 값으로neg_inf 초기화되는 것을 알 수 있습니다 . 컴파일러는 inf값 계산을 처리합니다 . 그리고 최대 값을 계산하기 위해 null 값으로 사용하면 일반적으로 첫 번째 반복이 더 큰 값으로 덮어 씁니다. 즉 성능은 거의 문제가되지 않습니다. 그리고 OP는 "예를 들어 음의 무한대를 사용하는 것"에 대해 구체적으로 묻고 -inf실제로 이것에 대한 유일한 정답입니다. 정확하고 유용한 답변에 반대표를 던졌습니다.
cmaster-모니카 복원
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.