2011-03-02 2 views
3

사용자가 다음과 같은 C++에서 int로 서명되지 않은 INT를 변환하는 효율적이고 문제없는 방법 다음C++에서 부호없는 int를 int로 변환하는 정수 오버플로를 피하는 효율적인 방법은 무엇입니까?

#include <limits.h> 
void safeConvert(unsigned int passed) 
{ 
    int variable = static_cast<int>(passed % (INT_MAX+1)); 
    ... 
} 

또는 더 나은 방법이?

UPDATE

으로는이 정수로 부호없는 INT> INT_MAX을 할당하는 정의되지되지 제임스 McNellis 지적 - 오히려이 정의 구현입니다. 이와 같은 문맥은 이제 부호가없는 int가 INT_MAX를 초과하면이 정수가 0으로 리셋되도록 보장하는 것이 내 선호에있다.

원본 문장

나는 부호 INT의 카운터로 사용의 번호를 가지고 있지만, 특정 경우에 정수로 주위를 전달하려는.

정상적인 작동 상태에서이 카운트는 INT_MAX의 범위 내에서 유지됩니다. 그러나 으로 실행하지 않으려면 구현 특정 동작을 수행해야합니다. 비정상적인 (그러나 유효한) 경우 발생합니다. 여기서 효율적인 변환을 원합니다.

+0

'safeConvert'가되어야하나요? 그래서, 입력이 INT_MAX보다 클 때 어떻게하고 싶습니까? 그런 경우에 몇 가지 플래그를 설정 하시겠습니까? –

+0

부호가있는 산술 연산에서 오버플로가 발생하면 정의되지 않은 동작이 발생하지만 부호있는 정수 유형으로 변환하지는 않습니다. 값을 대상 유형으로 나타낼 수없는 경우 결과는 구현에 따라 정의됩니다. –

+0

@Hamish 오타를 찾아 주셔서 감사합니다. 입력이 INT_MAX보다 큰 경우 int 값이> 0인지 확인하는 것이 좋습니다. –

답변

7

이것은 또한 작동합니다 :

int variable = passed & INT_MAX; 
+0

+1입니다. –

+0

@ 제리 : 나는 대개 설명보다는 코드를 작성하는 것이 빠르다는 것을 알게됩니다. 코드는 단지 밀도가 높고 간결하며 타이핑 속도는 적어도 나를위한 제한 요소입니다. –

+1

이 솔루션은 깔끔하지만 INT_MAX (일반적으로 2 ** n - 1로 정의 됨)의 구현 종속 속성을 사용합니다. OP의 목표는 구체적으로 구현 정의 동작을 피하는 것이 었습니다.가장 좋은 방법은 다음과 같습니다 * typedef char test [((INT_MAX + 1u) & (INT_MAX + 1u)) == 0]; * first;) – decltype

0

을 정상 운영이 카운트 INT_MAX의 범위 내에서 유지됩니다. 그러나 비정상적인 (그러나 유효한) 케이스가 발생하면 정의되지 않은 동작으로 실행되는 것을 피하기 위해 여기서 효율적인 변환을 원합니다.

효율적인 변환? int 및 unsigned int에 대한 모든 공유 값이 일치하고 INT_MAX + 1과 같은 다른 부호없는 값이 각각 고유 한 값을 갖기를 원하면 음의 정수 값으로 만 매핑 할 수 있습니다. 이는 기본적으로 수행되며 명시 적으로 static_cast<int>(my_unsigned)으로 요청할 수 있습니다. 그렇지 않으면 모두 0 또는 -1 또는 INT_MIN에 매핑하거나 높은 비트를 버리십시오. 가장 쉬운 방법은 간단히 : if (my_unsigned > INT_MAX) my_unsigned = XXX 또는 ...my_unsigned &= INT_MAX을 사용하여 상위 비트를 지울 수 있습니다. 그러나 int이 오버플로되면 호출 된 함수가 제대로 작동합니까? 아마도 더 좋은 해결책은 64 비트 int를 사용하여 시작하는 것입니다.

관련 문제