programing

휴대용으로 min(INT_MAX, abs(INT_MIN)을 찾는 방법은?

goodsources 2023. 10. 13. 22:05
반응형

휴대용으로 min(INT_MAX, abs(INT_MIN)을 찾는 방법은?

요를 알 수 ?INT_MAXINT_MIN입니다)? (입니다)INT_MIN, abs기능을 합니다.

은 같아야 합니다.INT_MAX대부분의 시스템에서 사용할 수 있습니다. 하지만 저는 좀 더 편리한 방법을 찾고 있습니다.

일반적인 가치는 다음과 같습니다.INT_MIN는 -2147483648이고, 일반적인 값은INT_MAX 표준에 2147483647,다.이 TL입니다.DR: 검색 중인 값은INT_MAX일치하는 실시로하지만 계산은 min(INT_MAX, abs(INT_MIN))휴대용이 아닙니다.


한 값은 INT_MIN그리고.INT_MAX

INT_MIN그리고.INT_MAX부속서 E(구현 한도) 1(C 표준, C++는 이를 상속함)에 의해 정의됩니다.

머리글의 내용은 알파벳 순으로 아래에 나와 있습니다.표시된 최소 크기는 동일한 기호를 가진 구현 정의된 크기로 대체해야 합니다.값은 모두 #if 전처리 지시에 사용하기에 적합한 일정한 표현이어야 합니다.구성요소에 대해서는 5.2.4.2.1에서 자세히 설명합니다.

[...]

#define INT_MAX +32767

#define INT_MIN -32767

[...]

합니다가 합니다.int 수 입니다.[INT_MIN, INT_MAX] (제5.2.4.2.1항).

그러면 6.2.6.2.(정수형, 역시 C 표준의 일부)가 작동하고 이것을 우리가 두 개 또는 의 보어라고 알고 있는 것으로 더욱 제한합니다.

부호가 있는 정수형의 경우 객체 표현의 비트를 값 비트, 패딩 비트, 부호 비트의 세 그룹으로 나눕니다.패딩 비트가 있을 필요는 없습니다. 부호가 있는 char에는 패딩 비트가 없어야 합니다.기호 비트가 정확히 하나일 것입니다.값 비트인 각 비트는 해당 비부호 유형의 객체 표현에서 동일한 비트와 동일한 값을 가져야 합니다(부호 유형에 M 값 비트가 있고 비부호 유형에 N 값 비트가 있으면 M ≤ N입니다).부호 비트가 0이면 결과 값에 영향을 주지 않습니다.부호 비트가 1이면 다음 중 하나의 방법으로 값을 수정해야 합니다.

— 부호 비트가 0인 해당 값은 음수입니다(부호 및 크기).

— 부호 비트는 -(2M) 값을 갖습니다(2의 보어);

— 부호 비트는 -(2M - 1)(자신의 보어) 값을 갖습니다.

섹션 6.2.6.2. 또한 서명된 정수형의 값 표현과 서명되지 않은 형제의 값 표현을 연관시키는 것이 매우 중요합니다.

이 말은, 당신이 그 범위를[-(2^n - 1), (2^n - 1)]아니면[-2^n, (2^n - 1)],어디에n일반적으로 15 또는 31입니다.

부호화된 정수 유형에 대한 연산

이제 두 번째 사항: 부호가 있는 정수 유형에 대한 연산, 결과적으로 범위 내에 있지 않은 값이 됩니다.[INT_MIN, INT_MAX], 동작이 정의되지 않았습니다.이는 C++에서 제5/4항에 의해 명시적으로 요구됩니다.

식을 평가하는 동안 결과가 수학적으로 정의되지 않거나 해당 유형에 대해 표현 가능한 값의 범위에 포함되지 않으면 동작이 정의되지 않습니다.

C의 경우 6.5/5가 매우 유사한 경로를 제공합니다.

식을 평가하는 동안 예외적인 조건이 발생하는 경우(즉, 결과가 수학적으로 정의되지 않았거나 해당 유형에 대해 표현 가능한 값의 범위에 있지 않은 경우), 동작은 정의되지 않습니다.

그러면 만약에 그 가치가INT_MIN우연히도 의 부정적인 것보다 적습니다.INT_MAX(예: 각각 -32768 및 32767)?계산중-(INT_MIN)다음과 같이 정의되지 않을 것입니다.INT_MAX + 1.

따라서 우리는 다음과 같은 범위에 있지 않을 수도 있는 값을 계산하는 것을 피해야 합니다.[INT_MIN, INT_MAX]. 운 좋게도.INT_MAX + INT_MIN항상 그 범위에 있습니다.INT_MAX이것은 엄밀하게 양의 값이고.INT_MIN엄밀한 음의 값이런 이유로INT_MIN < INT_MAX + INT_MIN < INT_MAX.

이제 확인해 볼 수 있습니다.INT_MAX + INT_MIN0보다 작거나 큰 값입니다.

`INT_MAX + INT_MIN`  |  value of -INT_MIN    | value of -INT_MAX 
------------------------------------------------------------------
         < 0         |  undefined            | -INT_MAX
         = 0         |  INT_MAX = -INT_MIN   | -INT_MAX = INT_MIN
         > 0         |  cannot occur according to 6.2.6.2. of the C standard

따라서, 다음의 최소값을 결정하기 위해INT_MAX그리고.-INT_MIN(수학적인 의미에서) 다음과 같은 코드로 충분합니다.

if ( INT_MAX + INT_MIN == 0 )
{
    return INT_MAX; // or -INT_MIN, it doesn't matter
}
else if ( INT_MAX + INT_MIN < 0 )
{
    return INT_MAX; // INT_MAX is smaller, -INT_MIN cannot be represented.
}
else // ( INT_MAX + INT_MIN > 0 )
{
    return -INT_MIN; // -INT_MIN is actually smaller than INT_MAX, may not occur in a conforming implementation.
}

또는 단순화하기 위해:

return (INT_MAX + INT_MIN <= 0) ? INT_MAX : -INT_MIN;

삼차 연산자의 값은 필요한 경우에만 평가됩니다.이런 이유로,-INT_MIN평가되지 않은 채로 있거나(따라서 UB를 생성할 수 없음), 잘 정의된 값입니다.

또는 주장을 원하는 경우:

assert(INT_MAX + INT_MIN <= 0);
return INT_MAX;

또는 컴파일 시간에 원하는 경우:

static_assert(INT_MAX + INT_MIN <= 0, "non-conforming implementation");
return INT_MAX;

정수 작업을 올바르게 수행하는 것(즉, 정확성이 중요한 경우)

안전한 정수 연산에 관심이 있다면 안전한 정수 연산을 구현해 보겠습니다.작업이 실패하고 성공한 패턴(이 긴 텍스트 출력 대신)을 보려면 이 데모를 선택합니다.

아키텍처에 따라 gcc의 옵션과 같이 정확성을 보장하는 다른 옵션이 있을 수 있습니다.-ftrapv.

INT_MAX + INT_MIN < 0 ? INT_MAX : -INT_MIN

편집하여 설명 추가:물론 어려운 점은-INT_MIN아니면abs(INT_MIN)다인 경우 .-INT_MIN너무 커서 안에 들어갈 수 없습니다.int 그래서 우리는 이것이 사실인지 확인할 방법이 필요합니다.n.INT_MAX + INT_MIN < 0 여부-INT_MIN.INT_MAX . .INT_MAX는 두 절대값 중 작은 값입니다.면.INT_MAX두에서 더 큰 이며,-INT_MIN정답입니다.

C99 에서,INT_MAX.

사양 변경:

부호가 있는 정수형의 경우 객체 표현의 비트를 값 비트, 패딩 비트, 부호 비트의 세 그룹으로 나눕니다.패딩 비트가 있을 필요는 없습니다. 부호가 있는 char에는 패딩 비트가 없어야 합니다.기호 비트가 정확히 하나일 것입니다.값 비트인 각 비트는 해당 비부호 유형의 객체 표현에서 동일한 비트와 동일한 값을 가져야 합니다(부호 유형에 M 값 비트가 있고 비부호 유형에 N 값 비트가 있으면 M ≤ N입니다).부호 비트가 0이면 결과 값에 영향을 주지 않습니다.부호 비트가 1이면 다음 중 하나의 방법으로 값을 수정해야 합니다.

  • 부호 비트가 0인 해당 값은 음수입니다(부호 및 크기).
  • 부호 비트는 -(2^M) 값을 갖습니다(2의 보어);
  • 부호 비트는 -(2^M - 1)(자신의 보어) 값을 갖습니다.

(http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf) 의 6.2.6.2절

대부분의 시스템에서 abs(INT_MIN)는 정의되지 않습니다.예를 들어 일반적인 32비트 시스템에서는 INT_MAX = 2^31 - 1, INT_MIN = - 2^31 및 abs(INT_MIN)는 2^31이 될 수 없습니다.

-INT_MAX할 수 있습니다.int모든 C와 C++ 방언에서 말이죠.따라서:

-INT_MAX <= INT_MIN ? -INT_MIN : INT_MAX

abs(INT_MIN)정의되지 않은 동작을 호출합니다.다라고 나와 있습니다.

7.22.6.abs,labs그리고.llabs함수:

abs,labs,그리고.llabs합니다.j 수 되지 않습니다 결과를 나타낼 수 없으면 동작이 정의되지 않습니다.

대신 이 방법을 사용해 보십시오.
tINT_MIN.unsignrd int는 .-수 unsigned int,INT_MAX다로 됩니다.UINT_MAX + 1 + INT_MIN.

#include <stdio.h>
#include <stdlib.h>

unsigned min(unsigned a, unsigned b)
{
    return a < b ? a : b;
}

int main(void)
{
    printf("%u\n", min(INT_MAX, INT_MIN));
}  

언급URL : https://stackoverflow.com/questions/29808397/how-to-portably-find-out-minint-max-absint-min

반응형