Problem
Consider 3 32-bit (4 byte) numbers A, B and C
A: A3 A2 A1 A0
B: B3 B2 B1 B0
C: C3 C2 C1 C0
Modify C such that
C0=(A0+B0)/2
C1=(A1+B1)/2
C2=(A2+B2)/2
C3=(A3+B3)/2
Without using the obvious method of masking out each byte of A and corresponding byte of B,
and add them, and then right-shifting once. Any other masking is allowed.
Solution
This is a simulation of pavgb in SIMD.
/*
============================================================================
Author : James Chen
Email : a.james.chen@gmail.com
Description : PAVGB simulation
Created Date : 21-06-2013
Last Modified :
============================================================================
*/
#include <iostream>
#include <iomanip>
using namespace std;
unsigned int PAVGB(unsigned int num1, unsigned int num2)
{
unsigned int mask01 = 0x01010101;
unsigned int maskFE = 0xFEFEFEFE;
unsigned int lsf = num1 & mask01;
lsf &= num2;
num1 &= maskFE;
num1 >>= 1;
num2 &= maskFE;
num2 >>= 1;
return (((num1 + num2) >> 1) << 1) + lsf;
}
void DoTest(unsigned int num1, unsigned int num2)
{
cout << "num 1 :";
cout << "0x" << setfill('0') << setw(8) << hex << num1 << endl;
cout << "num 2 :";
cout << "0x" << setfill('0') << setw(8) << hex << num2 << endl;
unsigned int output = PAVGB(num1, num2);
cout << "output :";
cout << "0x" << setfill('0') << setw(8) << hex << output << endl;
cout << "---------------------------" << endl;
}
int main(int argc, char* argv[])
{
cout << "Input 0, 0" << endl;
unsigned int num1 = 0;
unsigned int num2 = 0;
DoTest(num1, num2);
cout << "input 0xFFFFFFFF, 0xFFFFFFFF" << endl;
num1 = ~0;
num2 = ~0;
DoTest(num1, num2);
// Random input
cout << "Random input" << endl;
for(int i = 1; i < 20; ++i){
num1 = rand();
num2 = rand();
DoTest(num1, num2);
}
return 0;
}
Output
Input 0, 0
num 1 :0x00000000
num 2 :0x00000000
output :0x00000000
---------------------------
input 0xFFFFFFFF, 0xFFFFFFFF
num 1 :0xffffffff
num 2 :0xffffffff
output :0xffffffff
---------------------------
Random input
num 1 :0x00000029
num 2 :0x00004823
output :0x00002426
---------------------------
num 1 :0x000018be
num 2 :0x00006784
output :0x00003fa1
---------------------------
num 1 :0x00004ae1
num 2 :0x00003d6c
output :0x000043a6
---------------------------
num 1 :0x00002cd6
num 2 :0x000072ae
output :0x00004fc2
---------------------------
num 1 :0x00006952
num 2 :0x00005f90
output :0x00006471
---------------------------
num 1 :0x00001649
num 2 :0x00006df1
output :0x0000419d
---------------------------
num 1 :0x00005af1
num 2 :0x000041bb
output :0x00004dd6
---------------------------
num 1 :0x000026e9
num 2 :0x000001eb
output :0x000013ea
---------------------------
num 1 :0x00000bb3
num 2 :0x00002ea6
output :0x00001cac
---------------------------
num 1 :0x000012db
num 2 :0x0000153c
output :0x0000138b
---------------------------
num 1 :0x00007e87
num 2 :0x0000390c
output :0x00005b49
---------------------------
num 1 :0x00000f3e
num 2 :0x00000099
output :0x0000076b
---------------------------
num 1 :0x00000124
num 2 :0x0000305e
output :0x00001841
---------------------------
num 1 :0x0000440d
num 2 :0x0000491c
output :0x00004614
---------------------------
num 1 :0x00004d06
num 2 :0x00004db7
output :0x00004d5e
---------------------------
num 1 :0x00001547
num 2 :0x000054de
output :0x00003492
---------------------------
num 1 :0x000039b3
num 2 :0x00002d12
output :0x00003362
---------------------------
num 1 :0x0000074d
num 2 :0x00004dc8
output :0x00002a8a
---------------------------
num 1 :0x00006443
num 2 :0x000066bb
output :0x0000657f
---------------------------
Press any key to continue . . .