휴대용으로 min(INT_MAX, abs(INT_MIN)을 찾는 방법은?
요를 알 수 ?INT_MAX
INT_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_MIN
0보다 작거나 큰 값입니다.
`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
'programing' 카테고리의 다른 글
특정 폴더 안의 모든 파일을 읽는 방법 (0) | 2023.10.13 |
---|---|
AngularJS - 모델 값을 변경하는 지시에서 $render를 호출해야 하는 이유는 무엇입니까? (0) | 2023.10.13 |
루프로 각 $scope 변수를 반복하는 방법 (0) | 2023.10.13 |
커서에 무슨 문제가 있습니까? (0) | 2023.10.13 |
파이썬 플라스크 의도적 빈 반응 (0) | 2023.10.13 |