2017-02-17 1 views
3

많은 문제가 있으며 많은 최적화 방법을 찾을 수 없습니다.5/8 비트 씩 곱하기 오버플로 관찰

목표는 0을 향해 반올림하여 오버플로를 방지하는 것입니다. 작업 순서에 5를 곱한 다음 8로 나눈 값 (즉, 11 * 5/8 = 6)입니다. 최적화의 목표는 12 개 이하의 연산자를 사용하는 것입니다.

규정은 단지! ~ &^| + < < >> 연산과 8 비트 int가 허용됩니다. 솔루션에서

나의 현재 시도는 14 개 작업에 오면

int trueFiveEighths (int x){ 
    int rightOne = x >>1; 
    int rightTwo = x >>2; 
    int temp = (x &(rightTwo) &1) + (((x ^(rightTwo))|(rightOne)|x)&(x>>31)&1); 
    return (x>>3) + (rightOne) + temp; 
} 

입니다. 더 이상 통신 사업자를 면도 할 수있는 방법이 없으며 다른 방법을 찾아 낼 수 없습니다. 오에 의해 곱

int const rem = x & 7; 

각 :

int const eights = x >> 3; 

가 나머지를 얻을 :

eights += eights << 2; 
rem += rem << 2; 

을하고 새로운 wholes의 추가

+0

괄호 연산자입니다 (게임 보이/GBC) 내장 승수를하지 않았다 나는 시스템에서 돌아 오는 길에 기계에 사용했던 코드입니다 –

+0

나는 그들이 체커에 의해 계산되지 않았기 때문에 그들이 허용된다고 생각한다. – Falderol

+0

@ M.M : 분명히이 목적을 위해 아닙니다. – Ryan

답변

7

8 개의으로 나눌 수 있습니다

eights += rem >> 3; 

결합 :

int const eights = x >> 3; 
int const rem = x & 7; 

return eights + (eights << 2) + (rem + (rem << 2) >> 3); 

을 계산 사업자의 팔의 총.

8로 나눌 수없는 음수를 0으로 반올림하려면 부호 확장 (구현 정의, 이식성이 없지만 의도 한 해결책 일 수 있음)을 활용하여 음수에 대해 7을, 양수에 대해 0을 얻습니다 : 모두 함께

int const negative_mask = x >> 31 & 7; 

return eights + (eights << 2) + (rem + (rem << 2) + negative_mask >> 3); 

:

int const eights = x >> 3; 
int const rem = x & 7; 

return eights + (eights << 2) + (rem + (rem << 2) + (x >> 31 & 7) >> 3); 

(11) 운영자.

+1

을 수행하여 생성되었습니다. 오버플로를 처리합니다. –

+0

Checker에 따르면 it 그것은 0xb0000001 때 0xb0000000 제공함으로써 0x80000001 실패합니다. 0x80000000 0xb000000 않습니다 0xb000001 반환해야합니다 때문에이 포일이 및 혼란스런 제로 동작 향해 반올림합니다. 지금 작업. – Falderol

+1

@ Falderol : 오,이 서명 된 정수 에스? 오케이. 나에게 조금 줘 ... (또는 아마도 그것을 얻을거야!) – Ryan

0

여기에 4를 곱한 다음 X를 더해 5가되도록 한 다음 반올림을 위해 1/2 X를 더합니다. 그런 다음 8로 나누십시오 (교대 3).

return ((x << 2) + (x) + (x >> 1)) >> 3; 

우리가 처음 5 곱하기을하기 때문에 그 자체로, 0으로

return ((x << 2) + (x)) >> 3; 

이를 자르는 오버 플로우에 대해 보호되지 않습니다

. 먼저 아래로 내려갈 수는 있지만 정밀도는 떨어집니다. 믹스를 다운 시프트와 함께 사용하면 정밀도와 오버 플로우 방지 사이의 중간 지점을 제공 할 수 있습니다.

위의 방법은 거의 연산을 사용하는 장점을 가지고와