2013-05-31 1 views
2

나는 C가 쉬프트로부터 캐리 아웃 (carry-out)을 가지며 프로세서 특정 .h에서 찾을 수 있음을 읽었다.C가 << or a >> 비트 시프트에서 올림 비트를 보유합니까?

사실인가요? 사용해야합니까? 나 자신의 캐리 아웃 비트를 해결해야합니까?

+0

아마도 일부 asm 인라인이 작동합니다. –

+0

귀하의 유스 케이스에 대한 조사가 궁금합니다. 어셈블리 레벨에서 수행되면 일반적으로 레지스터의 비트 값을 순서대로 검사하는 기술입니다. C에서 이것을 수행하는 다른 방법은 carry-out을 확인하는 것을 포함하지 않습니다. 프로세서 별 구현이있는 경우 반복마다 마이크로 초로 등록하는 성능 조정이 필요하지 않으면 성능을 많이 얻지 못합니다. – lurker

답변

6

C.

당신은 더 큰 데이터 형식에 변화를 수행해야합니다 중 하나 원시적 인 작업의 캐리 비트 (들)에 액세스하기위한 표준 방법은 없습니다 :

uint16_t foo = ...; 

uint32_t tmp = (uint32_t)foo << shift; 
uint16_t result = (uint16_t)tmp; 
uint16_t carry = (uint16_t)(tmp >> 16); 

또는으로는 두 번째 방법은 정의되지 않은 동작 shift == 0 경우를 호출하는

uint16_t result = foo << shift; 
uint16_t carry = foo >> (16 - shift); 

주를, 그래서 당신은 별도로 경우를 처리하기 위해 필요한 것 : 반대 전환을 수행.

+0

네, 더 큰 데이터 타입으로가는 것이 가장 좋습니다. 참고 : 'shift <= 0'또는 'shift> = 16'인 경우 대답도 정의되지 않은 동작을 호출합니다. 그 케이스를 다루는 것은 당신의 훌륭한 대답을 사용하는 사람에게는 큰 도전이 아니어야합니다. – chux

+0

@chux : 감사합니다. 그러나 'shift'< 0 or > = 16은 UB이지만 두 번째 방법은'shift == 0'도 UB라는 것을 의미합니다. –

+0

리뷰에서 두 번째 방법에서 '0'의 이동이 좋다고 생각합니다. 물론 우리는 모두'uint16_t result = foo << 0'라고 생각하니 괜찮습니까? 하지만'uint16_t carry = foo >> 16 '이 정의되지 않았습니까? – chux

1

표준 C는 이 아니며,은 이동으로부터의 반출에 대한 액세스를 제공합니다.
일부는이 아닌 C 구현에는 프로세서 관련 .h 파일 또는 액세스를 허용하는 다른 확장이 있습니다.

실제적인 경우 processor-specific.h 파일 또는 확장 기능을 사용하지 마십시오. 그러나 사용을 의무화하는 경우 최소한 을 C 표준 솔루션으로 작성하십시오. 적어도 문서의 일부분입니다. 권장 @ 올리 Charlesworth 솔루션을 참조하십시오.

일반적으로 효과적인 이식성있는 코드를 만들려면 문제를 상위 수준에서 확인하고 수행을 사용하지 않아야합니다. 다른 한편, 이것이 좁은 범위의 기계를위한 것이라면, 당신 (또는 당신의 임금을 지불하는 사람들)에게 적합한 것을 가지고 가십시오.

이전에 게시 한 예에서 여러 가지 약점이 지적되었습니다. 나는 지금 이것을 구현에 의존하는 것으로 본다. 삭제되었습니다.

+0

당신은이 이식성에 관한이 경계를 말할 권리가 있습니다. 왼쪽으로 이동하는 음수 값은 정의되지 않은 동작입니다. * portable * 이외의 값입니다. 음수 값을 오른쪽으로 시프트하는 것은 구현 정의 동작이며, 앞으로는 어느 시점에서라도 서명 보존을 포함 할 수 있습니다. 둘 다 피해야합니다. – Sebivor

+0

@ undefined behavior "경계선"예제에 대한 평가에 동의하고 제거했습니다. – chux

관련 문제