2017-02-09 12 views
1

나는 5/8에 수를 곱하고 나머지가 0으로 반올림하는 비트 조작 방법을 사용합니다.이 방법은 효과적이며 거의 모든 것을 이해합니다. 그것의. 그러나 리뷰를 진행할 때, 0이 아닌 음수쪽으로 반올림되는 반올림 오류에 대해 anding 7 (00000111) 계정이 어떻게되는지를 알지 못해서 그 라인이 작동하는 이유를 이해해야합니다. 내가 볼 수있는 한 multiplyByFive 31 비트를 오른쪽으로 이동하면 변수의 부호를 확인하고 음수 인 경우 모든 부호를 반환하므로 양수인 경우 모두 0을 반환하고 음수 인 경우 이진수로 y를 모두내어 줄 것입니다. 내 이해가 올바른 경우, 왜 multiplyFiveEighths에 추가하고 8로 음수를 반올림하여 오류없이 빼기. 결과가 부정적이면비트 조작 - 분수로 A 음수를 곱하면 0 바이어스에 반올림 이해

int multFiveEights(int x) { 

5 곱한 후, 왼쪽에 4를 곱하여 그 두개로 이행 8 로 나누어 침입 내려 플러스 X는 5

int multiplyByFive = (x << 2) + x; 

하여 만든다 2^31 = 7

int addNumber = 7 & (multiplyByFive >> 31); 

11111111 교대 직전 (만약 당신이 (31)에 의해 오른쪽 시프트 때 부정적인 당신은 모두 1 수)

이있는 경우 긍정적이고 일 모두 0을 반환합니다 LSB multiplyByFive 7 오류

에 대한

계정 추가 부정적인

경우 경우의 그것이 더 음수 방향으로 이동하는 내림하려고, 그래서 그것을 AND 연산합니다 부정적 나머지 8 (항상 아래로 반올림)에 의해

int fiveEigths = (multiplyByFive + addNumber) >> 3; 
return fiveEigths; 
+0

'x '가 양수이면'x/8'이 왜 내림하지만 (x + 7)/8이 반올림하는 이유인지 이해합니까? – immibis

답변

1

addNumber은 음수 일 때 multiplyByFive이 음수 일 때 7이 될 것이며이 부분을 이해한다고 가정합니다.

따라서 로직은 음수 인 경우에만 오른쪽 시프 팅 3 이전에 multiplyByFive에 7을 더하는 것입니다.

왜이 기능이 작동하는지 이해하려면 아래쪽 3 비트 수로 반올림 및 반올림의 차이점을 고려하십시오.

숫자가 8의 배수가되기 때문에 반올림이 필요하지 않으므로 아래의 3 비트가 0 일 때 반올림 및 반올림으로 차이가 발생하지 않습니다. 3만큼 시프트)는 정수 결과를 생성합니다.

하위 3 비트가 다른 경우, 반올림 한 경우보다 반올림 한 최종 결과는 1이됩니다.

7을 더하면 하위 3 비트가 0이 될 때를 제외하고 각 경우의 4 번째 비트를 클로킹하여 최종 결과가 1 씩 증가합니다. 모두 0 인 경우 7을 추가하면 하위 3 비트가 1로 설정되지만 4 단에는 영향을 미치지 않으므로 이동 결과가 변경되지 않습니다.

1

(multiplyByFive + 0) >> 3 분할에 대해이 오류/테스트를위한 7 개 계정 및 8에 의해
(multiplyByFive + 7) >> 3 분할로 (항상 반올림).

코드가 0 인 방향을 확인한 다음 그 방향으로 반올림하여 코드가 항상 0으로 반올림됩니다. 나눌 숫자가 음수이면 7을 더한 후 반올림합니다 (0을 향함). 양수이면 0을 더하기 때문에 반올림합니다 (또한 0으로 설정 됨).